PC_Device.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. #ifndef _XBOX
  2. #include "PC_Device.h"
  3. #include "..\Render.h"
  4. #include "..\RenderTargets\RenderTarget.h"
  5. #include "..\RenderTargets\RenderTargetDepth.h"
  6. DX9RenderDevice::DX9RenderDevice(bool bMaximimize, bool bExpand)
  7. {
  8. m_bMaximimize = bMaximimize;
  9. m_bExpand = bExpand;
  10. bPerfHudDevice = false;
  11. d3d_device = NULL;
  12. current_RT = NULL;
  13. current_RT_depth = NULL;
  14. default_RT = NULL;
  15. default_RT_depth = NULL;
  16. }
  17. DX9RenderDevice::~DX9RenderDevice()
  18. {
  19. RELEASE_D3D(d3d_device, 0);
  20. }
  21. void DX9RenderDevice::Cleanup ()
  22. {
  23. FORCERELEASE (default_RT);
  24. FORCERELEASE (default_RT_depth);
  25. }
  26. void DX9RenderDevice::Init ()
  27. {
  28. }
  29. void DX9RenderDevice::Lost ()
  30. {
  31. if (default_RT)
  32. {
  33. default_RT->OnLostDevice();
  34. }
  35. if (default_RT_depth)
  36. {
  37. default_RT_depth->OnLostDevice();
  38. }
  39. }
  40. void DX9RenderDevice::Reset ()
  41. {
  42. IDirect3DSurface9* m_pDefaultSurface = NULL;
  43. IDirect3DSurface9* m_pDefaultDepthSurface = NULL;
  44. HRESULT hr = D3D()->GetRenderTarget(0, &m_pDefaultSurface);
  45. Assert(hr == D3D_OK);
  46. hr = D3D()->GetDepthStencilSurface(&m_pDefaultDepthSurface);
  47. Assert(hr == D3D_OK);
  48. current_RT = NULL;
  49. current_RT_depth = NULL;
  50. default_RT->CreateFromDX(m_pDefaultSurface, true);
  51. default_RT_depth->CreateFromDX(m_pDefaultDepthSurface, true);
  52. current_RT = default_RT;
  53. current_RT_depth = default_RT_depth;
  54. if (m_pDefaultDepthSurface != NULL)
  55. {
  56. hr = D3D()->Clear( 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0x0, 1.0, 0x0);
  57. Assert(hr == D3D_OK);
  58. } else
  59. {
  60. hr = D3D()->Clear( 0, NULL, D3DCLEAR_TARGET, 0x0, 1.0, 0x0);
  61. Assert(hr == D3D_OK);
  62. }
  63. }
  64. bool DX9RenderDevice::DisableStateManager ()
  65. {
  66. return false;
  67. //return true;
  68. }
  69. bool DX9RenderDevice::Create (IDirect3D9* d3d9, D3DPRESENT_PARAMETERS &params, long deviceIndex, RENDERSCREEN & m_Screen2DInfo, RENDERSCREEN & m_Screen3DInfo)
  70. {
  71. d3d_device = NULL;
  72. UINT AdapterToUse = deviceIndex;
  73. D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL;
  74. #ifndef STOP_DEBUG
  75. #ifndef _XBOX
  76. // Look for 'NVIDIA NVPerfHUD' adapter
  77. // If it is present, override default settings
  78. for (UINT Adapter = 0; Adapter < d3d9->GetAdapterCount(); Adapter++)
  79. {
  80. D3DADAPTER_IDENTIFIER9 Identifier;
  81. HRESULT Res;
  82. Res = d3d9->GetAdapterIdentifier(Adapter, 0, &Identifier);
  83. api->Trace("Adapter : '%s'", Identifier.Description);
  84. if (strcmp(Identifier.Description, "NVIDIA NVPerfHUD") == 0 || strcmp(Identifier.Description, "NVIDIA PerfHUD") == 0)
  85. {
  86. api->Trace("Use : NVIDIA NVPerfHUD device");
  87. bPerfHudDevice = true;
  88. AdapterToUse = Adapter;
  89. DeviceType = D3DDEVTYPE_REF;
  90. break;
  91. }
  92. }
  93. #endif
  94. #endif
  95. #ifndef _XBOX
  96. if (params.Windowed)
  97. {
  98. HWND winHandle = (HWND)api->Storage().GetLong("system.hwnd");
  99. WINDOWINFO savedInfo;
  100. GetWindowInfo(winHandle, &savedInfo);
  101. if (m_bMaximimize)
  102. {
  103. MONITORINFO miMonInfo = { 0 };
  104. miMonInfo.cbSize = sizeof( miMonInfo );
  105. HMONITOR hMonitor = MonitorFromWindow( winHandle, MONITOR_DEFAULTTONEAREST );
  106. GetMonitorInfo( hMonitor, &miMonInfo );
  107. SetWindowPos(winHandle, HWND_NOTOPMOST, miMonInfo.rcMonitor.left, miMonInfo.rcMonitor.top, miMonInfo.rcMonitor.right-miMonInfo.rcMonitor.left, miMonInfo.rcMonitor.bottom-miMonInfo.rcMonitor.top, SWP_NOOWNERZORDER);
  108. } else
  109. {
  110. RECT r;
  111. r.left = 0;
  112. r.right = r.left + params.BackBufferWidth;
  113. r.top = 0;
  114. r.bottom = r.top + params.BackBufferHeight;
  115. DWORD dwFlags = DS_MODALFRAME | DS_FIXEDSYS | WS_CAPTION | WS_BORDER | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
  116. dwFlags = dwFlags & ~WS_THICKFRAME;
  117. DWORD dwExFlags = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE;
  118. AdjustWindowRect(&r, dwFlags, 0);
  119. SetWindowLong(winHandle, GWL_STYLE, dwFlags);
  120. SetWindowLong(winHandle, GWL_EXSTYLE, dwExFlags);
  121. SetWindowPos(winHandle, HWND_NOTOPMOST, r.left, r.top, r.right-r.left, r.bottom-r.top, SWP_NOOWNERZORDER);
  122. if (m_bExpand)
  123. {
  124. SetWindowLong(winHandle, GWL_STYLE, dwFlags | WS_MAXIMIZEBOX);
  125. ShowWindow(winHandle, SW_MAXIMIZE);
  126. }
  127. }
  128. WINDOWINFO info;
  129. info.cbSize = sizeof(WINDOWINFO);
  130. GetWindowInfo(winHandle, &info);
  131. DWORD dwW = info.rcClient.right - info.rcClient.left;
  132. DWORD dwH = info.rcClient.bottom - info.rcClient.top;
  133. params.BackBufferWidth = dwW;
  134. params.BackBufferHeight = dwH;
  135. SetWindowLong(winHandle, GWL_STYLE, savedInfo.dwStyle);
  136. SetWindowLong(winHandle, GWL_EXSTYLE, savedInfo.dwExStyle);
  137. SetWindowPos(winHandle, HWND_NOTOPMOST, savedInfo.rcWindow.left, savedInfo.rcWindow.top, savedInfo.rcWindow.right-savedInfo.rcWindow.left, savedInfo.rcWindow.bottom-savedInfo.rcWindow.top, SWP_NOOWNERZORDER);
  138. }
  139. #endif
  140. if (d3d9->CreateDevice(AdapterToUse, DeviceType, (HWND)api->Storage().GetLong("system.hwnd"), D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE | D3DCREATE_MULTITHREADED, &params, &d3d_device) != D3D_OK)
  141. {
  142. if (d3d9->CreateDevice(AdapterToUse, DeviceType, (HWND)api->Storage().GetLong("system.hwnd"), D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &params, &d3d_device) != D3D_OK)
  143. {
  144. api->Trace("Can't create Direct3D Device !");
  145. return false;
  146. }
  147. }
  148. CDX8IBuffer::pD3D8 = D3D();
  149. CDX8VBuffer::pD3D8 = D3D();
  150. CDX8Texture::pD3D8 = D3D();
  151. Shader::pD3D8 = D3D();
  152. StateFilter::pD3D8 = D3D();
  153. IDirect3DSurface9* m_pDefaultSurface = NULL;
  154. IDirect3DSurface9* m_pDefaultDepthSurface = NULL;
  155. HRESULT hr = D3D()->GetRenderTarget(0, &m_pDefaultSurface);
  156. Assert(hr == D3D_OK);
  157. hr = D3D()->GetDepthStencilSurface(&m_pDefaultDepthSurface);
  158. Assert(hr == D3D_OK);
  159. current_RT = NULL;
  160. current_RT_depth = NULL;
  161. default_RT = NEW RenderTarget;
  162. default_RT->CreateFromDX(m_pDefaultSurface, false);
  163. default_RT_depth = NEW RenderTargetDepth;
  164. default_RT_depth->CreateFromDX(m_pDefaultDepthSurface, false);
  165. current_RT = default_RT;
  166. current_RT_depth = default_RT_depth;
  167. if (m_pDefaultDepthSurface != NULL)
  168. {
  169. hr = D3D()->Clear( 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0x0, 1.0, 0x0);
  170. Assert(hr == D3D_OK);
  171. } else
  172. {
  173. hr = D3D()->Clear( 0, NULL, D3DCLEAR_TARGET, 0x0, 1.0, 0x0);
  174. Assert(hr == D3D_OK);
  175. }
  176. m_Screen2DInfo.dwWidth = params.BackBufferWidth;
  177. m_Screen2DInfo.dwHeight = params.BackBufferHeight;
  178. m_Screen2DInfo.BackBufferFormat = FormatFromDX(params.BackBufferFormat);
  179. m_Screen3DInfo = m_Screen2DInfo;
  180. return true;
  181. }
  182. void DX9RenderDevice::AdjustWindow(long x, long y, bool bExpand, bool bMaximize, D3DPRESENT_PARAMETERS &params)
  183. {
  184. if (params.Windowed == false) return;
  185. HWND winHandle = (HWND)api->Storage().GetLong("system.hwnd");
  186. if (bMaximize)
  187. {
  188. //SetWindowLong(winHandle, GWL_STYLE, WS_POPUP | WS_VISIBLE);
  189. MONITORINFO miMonInfo = { 0 };
  190. miMonInfo.cbSize = sizeof( miMonInfo );
  191. HMONITOR hMonitor = MonitorFromWindow( winHandle, MONITOR_DEFAULTTONEAREST );
  192. GetMonitorInfo( hMonitor, &miMonInfo );
  193. //miMonInfo.
  194. SetWindowPos(winHandle, HWND_NOTOPMOST, miMonInfo.rcMonitor.left, miMonInfo.rcMonitor.top, miMonInfo.rcMonitor.right-miMonInfo.rcMonitor.left, miMonInfo.rcMonitor.bottom-miMonInfo.rcMonitor.top, SWP_NOOWNERZORDER);
  195. } else
  196. {
  197. RECT r;
  198. r.left = x;
  199. r.right = r.left + params.BackBufferWidth;
  200. r.top = y;
  201. r.bottom = r.top + params.BackBufferHeight;
  202. DWORD dwFlags = DS_MODALFRAME | DS_FIXEDSYS | WS_CAPTION | WS_BORDER | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
  203. dwFlags = dwFlags & ~WS_THICKFRAME;
  204. DWORD dwExFlags = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE;
  205. AdjustWindowRect(&r, dwFlags, 0);
  206. SetWindowLong(winHandle, GWL_STYLE, dwFlags);
  207. SetWindowLong(winHandle, GWL_EXSTYLE, dwExFlags);
  208. SetWindowPos(winHandle, HWND_NOTOPMOST, r.left, r.top, r.right-r.left, r.bottom-r.top, SWP_NOOWNERZORDER);
  209. if (bExpand)
  210. {
  211. SetWindowLong(winHandle, GWL_STYLE, dwFlags | WS_MAXIMIZEBOX);
  212. ShowWindow(winHandle, SW_MAXIMIZE);
  213. }
  214. }
  215. WINDOWINFO info;
  216. info.cbSize = sizeof(WINDOWINFO);
  217. GetWindowInfo(winHandle, &info);
  218. DWORD dwW = info.rcClient.right - info.rcClient.left;
  219. DWORD dwH = info.rcClient.bottom - info.rcClient.top;
  220. api->Trace("client size %d x %d", dwW, dwH);
  221. }
  222. void DX9RenderDevice::Present ()
  223. {
  224. if (NGRender::pRS->IsRenderDisabled()) return;
  225. HRESULT hr = D3D()->Present(NULL, NULL, NULL, NULL );
  226. //Assert(hr == D3D_OK);
  227. }
  228. void DX9RenderDevice::BeginScene ()
  229. {
  230. HRESULT hr = D3D()->BeginScene();
  231. Assert(hr == D3D_OK);
  232. }
  233. void DX9RenderDevice::EndScene (IBaseTexture* pDestiantionTexture, bool bSkipAnyWork, bool bDontResolveDepthOnX360)
  234. {
  235. HRESULT hr = D3D()->EndScene();
  236. Assert(hr == D3D_OK);
  237. if (bSkipAnyWork)
  238. {
  239. return;
  240. }
  241. if (current_RT)
  242. {
  243. RenderTarget* curRT = (RenderTarget*)current_RT;
  244. if (pDestiantionTexture)
  245. {
  246. curRT->CopyToTexture(pDestiantionTexture);
  247. }
  248. if (curRT->NeedCopy ())
  249. {
  250. #ifndef _XBOX
  251. long mipCount = ((RenderTarget*)current_RT)->GetMipCount();
  252. for (long i = 0; i < mipCount; i++)
  253. {
  254. IDirect3DSurface9* dest = ((RenderTarget*)current_RT)->GetTextureSurface(i);
  255. IDirect3DSurface9* src = ((RenderTarget*)current_RT)->GetD3DSurface();
  256. if (src && dest)
  257. {
  258. hr = D3D()->StretchRect(src, NULL, dest, NULL, D3DTEXF_LINEAR);
  259. }
  260. }
  261. #else
  262. //!!! throw;
  263. #endif
  264. }
  265. }
  266. }
  267. void DX9RenderDevice::SetRenderTarget (RenderTartgetOptions options, IRenderTarget* renderTarget, IRenderTargetDepth* renderTargetDepth)
  268. {
  269. current_RT = renderTarget;
  270. current_RT_depth = renderTargetDepth;
  271. IDirect3DSurface9* d3d_colorSurface = NULL;
  272. IDirect3DSurface9* d3d_depthSurface = NULL;
  273. if (renderTarget)
  274. {
  275. d3d_colorSurface = ((RenderTarget*)renderTarget)->GetD3DSurface ();
  276. }
  277. if (renderTargetDepth)
  278. {
  279. d3d_depthSurface = ((RenderTargetDepth*)renderTargetDepth)->GetD3DSurface ();
  280. }
  281. for (dword n =0 ; n < 16; n++)
  282. {
  283. NGRender::pRS->D3D()->SetTexture(n, NULL);
  284. }
  285. HRESULT hr = D3D()->SetRenderTarget(0, d3d_colorSurface);
  286. Assert(hr == D3D_OK);
  287. hr = D3D()->SetDepthStencilSurface(d3d_depthSurface);
  288. Assert(hr == D3D_OK);
  289. /*if (options == RTO_DONTOCH_CONTEXT)
  290. {
  291. //эмулируем разрушение в EDRAM
  292. dword dwFlags = D3DCLEAR_TARGET;
  293. if (d3d_depthSurface)
  294. {
  295. dwFlags = dwFlags | D3DCLEAR_ZBUFFER;
  296. }
  297. hr = D3D()->Clear( 0, NULL, dwFlags, rand(), 1.0, rand());
  298. Assert(hr == D3D_OK);
  299. }*/
  300. }
  301. void DX9RenderDevice::GetRenderTarget (IRenderTarget** renderTarget, IRenderTargetDepth** renderTargetDepth)
  302. {
  303. if (renderTarget)
  304. {
  305. *renderTarget = current_RT;
  306. }
  307. if (renderTargetDepth)
  308. {
  309. *renderTargetDepth = current_RT_depth;
  310. }
  311. }
  312. IDirect3DDevice9* DX9RenderDevice::D3D()
  313. {
  314. return d3d_device;
  315. }
  316. void DX9RenderDevice::ResolveColor (IBaseTexture * dest)
  317. {
  318. if (current_RT && dest)
  319. {
  320. RENDERSURFACE_DESC desc1;
  321. current_RT_depth->GetDesc(&desc1);
  322. dword dwTexWidth = dest->GetWidth();
  323. dword dwTexHeight = dest->GetHeight();
  324. Assert(desc1.Width == dwTexWidth);
  325. Assert(desc1.Height == dwTexHeight);
  326. //Assert(desc1.MultiSampleType == desc2.MultiSampleType);
  327. //Assert(desc1.MultiSampleQuality == desc2.MultiSampleQuality);
  328. IDirect3DTexture9* color_tex = (IDirect3DTexture9*)dest->GetBaseTexture();
  329. IDirect3DSurface9* srcDepthSurface = ((RenderTarget*)current_RT)->GetD3DSurface();
  330. IDirect3DSurface9* destDepthSurface = NULL;
  331. color_tex->GetSurfaceLevel(0, &destDepthSurface);
  332. HRESULT hr = D3D()->StretchRect(srcDepthSurface, NULL, destDepthSurface, NULL, D3DTEXF_NONE);
  333. destDepthSurface->Release();
  334. }
  335. }
  336. void DX9RenderDevice::ResolveDepth (IRenderTargetDepth* dest)
  337. {
  338. if (current_RT_depth && dest)
  339. {
  340. RENDERSURFACE_DESC desc1;
  341. RENDERSURFACE_DESC desc2;
  342. current_RT_depth->GetDesc(&desc1);
  343. dest->GetDesc(&desc2);
  344. Assert(desc1.Width == desc2.Width);
  345. Assert(desc1.Height == desc2.Height);
  346. //Assert(desc1.MultiSampleType == desc2.MultiSampleType);
  347. //Assert(desc1.MultiSampleQuality == desc2.MultiSampleQuality);
  348. IDirect3DSurface9* srcDepthSurface = ((RenderTargetDepth*)current_RT_depth)->GetD3DSurface();
  349. IDirect3DSurface9* destDepthSurface = ((RenderTargetDepth*)dest)->GetD3DSurface();
  350. HRESULT hr = D3D()->StretchRect(srcDepthSurface, NULL, destDepthSurface, NULL, D3DTEXF_NONE);
  351. }
  352. }
  353. #endif