Windows: Link debug build against debug wiiuse. Can't keep linking to the release...
[dolphin.git] / Source / Plugins / Plugin_VideoDX11 / Src / main.cpp
blob699636bc4c72fb5fc940590fecd6daf65878c8fb
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 "FramebufferManager.h"
56 #include "DLCache.h"
58 HINSTANCE g_hInstance = NULL;
59 SVideoInitialize g_VideoInitialize;
60 PLUGIN_GLOBALS* globals = NULL;
61 static bool s_PluginInitialized = false;
63 volatile u32 s_swapRequested = FALSE;
64 static u32 s_efbAccessRequested = FALSE;
65 static volatile u32 s_FifoShuttingDown = FALSE;
67 static volatile struct
69 u32 xfbAddr;
70 FieldType field;
71 u32 fbWidth;
72 u32 fbHeight;
73 } s_beginFieldArgs;
75 static volatile EFBAccessType s_AccessEFBType;
77 bool IsD3D()
79 return true;
82 // This is used for the functions right below here which use wxwidgets
83 #if defined(HAVE_WX) && HAVE_WX
84 WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
85 #endif
87 void *DllDebugger(void *_hParent, bool Show)
89 return NULL;
92 #if defined(HAVE_WX) && HAVE_WX
93 class wxDLLApp : public wxApp
95 bool OnInit()
97 return true;
100 IMPLEMENT_APP_NO_MAIN(wxDLLApp)
101 WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
102 #endif
104 BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
106 switch (dwReason)
108 case DLL_PROCESS_ATTACH:
110 #if defined(HAVE_WX) && HAVE_WX
111 wxSetInstance((HINSTANCE)hinstDLL);
112 wxInitialize();
113 #endif
115 break;
116 case DLL_PROCESS_DETACH:
117 #if defined(HAVE_WX) && HAVE_WX
118 wxUninitialize();
119 #endif
120 break;
123 g_hInstance = hinstDLL;
124 return TRUE;
127 unsigned int Callback_PeekMessages()
129 MSG msg;
130 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
132 if (msg.message == WM_QUIT)
133 return FALSE;
134 TranslateMessage(&msg);
135 DispatchMessage(&msg);
137 return TRUE;
141 void UpdateFPSDisplay(const char *text)
143 char temp[512];
144 sprintf_s(temp, 512, "SVN R%s: DX11: %s", svn_rev_str, text);
145 SetWindowTextA(EmuWindow::GetWnd(), temp);
148 void GetDllInfo(PLUGIN_INFO* _PluginInfo)
150 _PluginInfo->Version = 0x0100;
151 _PluginInfo->Type = PLUGIN_TYPE_VIDEO;
152 #ifdef DEBUGFAST
153 sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D11 (DebugFast)");
154 #elif defined _DEBUG
155 sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D11 (Debug)");
156 #else
157 sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D11");
158 #endif
161 void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
163 globals = _pPluginGlobals;
164 LogManager::SetInstance((LogManager*)globals->logManager);
167 void DllConfig(void *_hParent)
169 DlgSettings_Show(g_hInstance, (HWND)((wxWindow *)_hParent)->GetHandle());
172 void Initialize(void *init)
174 frameCount = 0;
175 SVideoInitialize *_pVideoInitialize = (SVideoInitialize*)init;
176 // Create a shortcut to _pVideoInitialize that can also update it
177 g_VideoInitialize = *(_pVideoInitialize);
178 InitXFBConvTables();
180 g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx11.ini").c_str());
181 g_Config.GameIniLoad(globals->game_ini);
182 UpdateActiveConfig();
184 g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create((HWND)g_VideoInitialize.pWindowHandle, g_hInstance, _T("Loading - Please wait."));
185 if (g_VideoInitialize.pWindowHandle == NULL)
187 ERROR_LOG(VIDEO, "An error has occurred while trying to create the window.");
188 return;
191 g_VideoInitialize.pPeekMessages = &Callback_PeekMessages;
192 g_VideoInitialize.pUpdateFPSDisplay = &UpdateFPSDisplay;
194 _pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
195 _pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
197 // Now the window handle is written
198 _pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
200 OSD::AddMessage("Dolphin Direct3D11 Video Plugin.", 5000);
201 s_PluginInitialized = true;
204 void Video_Prepare()
206 // Better be safe...
207 s_efbAccessRequested = FALSE;
208 s_FifoShuttingDown = FALSE;
209 s_swapRequested = FALSE;
211 // internal interfaces
212 Renderer::Init();
213 g_texture_cache = new DX11::TextureCache;
214 g_vertex_manager = new DX11::VertexManager;
215 VertexShaderCache::Init();
216 PixelShaderCache::Init();
217 D3D::InitUtils();
219 // VideoCommon
220 BPInit();
221 Fifo_Init();
222 VertexLoaderManager::Init();
223 OpcodeDecoder_Init();
224 VertexShaderManager::Init();
225 PixelShaderManager::Init();
226 CommandProcessor::Init();
227 PixelEngine::Init();
228 DLCache::Init();
230 // Tell the host that the window is ready
231 g_VideoInitialize.pCoreMessage(WM_USER_CREATE);
234 void Shutdown()
236 s_PluginInitialized = false;
238 s_efbAccessRequested = FALSE;
239 s_FifoShuttingDown = FALSE;
240 s_swapRequested = FALSE;
242 // VideoCommon
243 DLCache::Shutdown();
244 Fifo_Shutdown();
245 CommandProcessor::Shutdown();
246 PixelShaderManager::Shutdown();
247 VertexShaderManager::Shutdown();
248 OpcodeDecoder_Shutdown();
249 VertexLoaderManager::Shutdown();
251 // internal interfaces
252 D3D::ShutdownUtils();
253 PixelShaderCache::Shutdown();
254 VertexShaderCache::Shutdown();
255 delete g_vertex_manager;
256 delete g_texture_cache;
257 Renderer::Shutdown();
258 EmuWindow::Close();
260 s_PluginInitialized = false;
263 void DoState(unsigned char **ptr, int mode)
265 // Clear texture cache because it might have written to RAM
266 CommandProcessor::FifoCriticalEnter();
267 TextureCache::Invalidate(false);
268 CommandProcessor::FifoCriticalLeave();
269 // No need to clear shader caches
270 PointerWrap p(ptr, mode);
271 VideoCommon_DoState(p);
274 void EmuStateChange(PLUGIN_EMUSTATE newState)
276 Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false);
279 // Enter and exit the video loop
280 void Video_EnterLoop()
282 Fifo_EnterLoop(g_VideoInitialize);
285 void Video_ExitLoop()
287 Fifo_ExitLoop();
288 s_FifoShuttingDown = TRUE;
291 void Video_SetRendering(bool bEnabled)
293 Fifo_SetRendering(bEnabled);
296 // Run from the graphics thread (from Fifo.cpp)
297 void VideoFifo_CheckSwapRequest()
299 if(g_ActiveConfig.bUseXFB)
301 if (Common::AtomicLoadAcquire(s_swapRequested))
303 EFBRectangle rc;
304 Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc);
305 Common::AtomicStoreRelease(s_swapRequested, FALSE);
310 // Run from the graphics thread (from Fifo.cpp)
311 void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
313 if (g_ActiveConfig.bUseXFB)
315 if(Common::AtomicLoadAcquire(s_swapRequested))
317 u32 aLower = xfbAddr;
318 u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight;
319 u32 bLower = s_beginFieldArgs.xfbAddr;
320 u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbWidth * s_beginFieldArgs.fbHeight;
322 if (addrRangesOverlap(aLower, aUpper, bLower, bUpper))
323 VideoFifo_CheckSwapRequest();
328 // Run from the CPU thread (from VideoInterface.cpp)
329 void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
331 if (s_PluginInitialized && g_ActiveConfig.bUseXFB)
333 if (!g_VideoInitialize.bOnThread)
334 VideoFifo_CheckSwapRequest();
335 s_beginFieldArgs.xfbAddr = xfbAddr;
336 s_beginFieldArgs.field = field;
337 s_beginFieldArgs.fbWidth = fbWidth;
338 s_beginFieldArgs.fbHeight = fbHeight;
342 // Run from the CPU thread (from VideoInterface.cpp)
343 void Video_EndField()
345 if (s_PluginInitialized)
347 Common::AtomicStoreRelease(s_swapRequested, TRUE);
351 void Video_AddMessage(const char* pstr, u32 milliseconds)
353 OSD::AddMessage(pstr, milliseconds);
356 // Screenshot
357 void Video_Screenshot(const char *_szFilename)
359 Renderer::SetScreenshot(_szFilename);
362 static struct
364 EFBAccessType type;
365 u32 x;
366 u32 y;
367 u32 Data;
368 } s_accessEFBArgs;
370 static u32 s_AccessEFBResult = 0;
372 void VideoFifo_CheckEFBAccess()
374 if (Common::AtomicLoadAcquire(s_efbAccessRequested))
376 s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data);
378 Common::AtomicStoreRelease(s_efbAccessRequested, FALSE);
382 u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
384 if (s_PluginInitialized)
386 s_accessEFBArgs.type = type;
387 s_accessEFBArgs.x = x;
388 s_accessEFBArgs.y = y;
389 s_accessEFBArgs.Data = InputData;
391 Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
393 if (g_VideoInitialize.bOnThread)
395 while (Common::AtomicLoadAcquire(s_efbAccessRequested) && !s_FifoShuttingDown)
396 //Common::SleepCurrentThread(1);
397 Common::YieldCPU();
399 else
400 VideoFifo_CheckEFBAccess();
402 return s_AccessEFBResult;
405 return 0;
408 void VideoFifo_CheckAsyncRequest() {
409 VideoFifo_CheckSwapRequest();
410 VideoFifo_CheckEFBAccess();
413 void Video_CommandProcessorRead16(u16& _rReturnValue, const u32 _Address)
415 CommandProcessor::Read16(_rReturnValue, _Address);
418 void Video_CommandProcessorWrite16(const u16 _Data, const u32 _Address)
420 CommandProcessor::Write16(_Data, _Address);
423 void Video_PixelEngineRead16(u16& _rReturnValue, const u32 _Address)
425 PixelEngine::Read16(_rReturnValue, _Address);
428 void Video_PixelEngineWrite16(const u16 _Data, const u32 _Address)
430 PixelEngine::Write16(_Data, _Address);
433 void Video_PixelEngineWrite32(const u32 _Data, const u32 _Address)
435 PixelEngine::Write32(_Data, _Address);
438 void Video_GatherPipeBursted(void)
440 CommandProcessor::GatherPipeBursted();
443 void Video_WaitForFrameFinish(void)
445 CommandProcessor::WaitForFrameFinish();
448 bool Video_IsFifoBusy(void)
450 return CommandProcessor::isFifoBusy;
453 void Video_AbortFrame(void)
455 CommandProcessor::AbortFrame();