Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1696 lines
46 KiB

  1. //===== Copyright © 1996-2008, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #ifndef D3DASYNC_H
  9. #define D3DASYNC_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. // Set this to 1 to allow d3d calls to be buffered and played back on another thread
  14. #define SHADERAPI_USE_SMP 1
  15. // Set this to 1 to allow buffering of the whole frame to memory and then playback (singlethreaded).
  16. // This is for debugging only and is used to test the performance of just calling D3D and rendering without other CPU overhead.
  17. #define SHADERAPI_BUFFER_D3DCALLS 0
  18. #if SHADERAPI_BUFFER_D3DCALLS && !SHADERAPI_USE_SMP
  19. # error "SHADERAPI_USE_SMP must be 1 for SHADERAPI_BUFFER_D3DCALLS to work!"
  20. #endif
  21. #include "recording.h"
  22. #include "strtools.h"
  23. #include "tier0/vprof_telemetry.h"
  24. #if ( IS_WINDOWS_PC )
  25. #define NO_STEREO_D3D10 1
  26. #ifdef DX_TO_GL_ABSTRACTION
  27. #define NO_STEREO_D3D9 1
  28. #endif
  29. #include "hl2stereo.h"
  30. #endif
  31. #ifdef NDEBUG
  32. #define DO_D3D(x) Dx9Device()->x
  33. #else
  34. #define DO_D3D(x) Dx9Device()->x
  35. //#define DO_D3D(x) { HRESULT hr=Dx9Device()->x; Assert( !FAILED(hr) ); }
  36. #endif
  37. #define PUSHBUFFER_NELEMS 4096
  38. enum PushBufferState
  39. {
  40. PUSHBUFFER_AVAILABLE,
  41. PUSHBUFFER_BEING_FILLED,
  42. PUSHBUFFER_SUBMITTED,
  43. PUSHBUFFER_BEING_USED_FOR_LOCKEDDATA,
  44. };
  45. class PushBuffer
  46. {
  47. friend class D3DDeviceWrapper;
  48. volatile PushBufferState m_State;
  49. uint32 m_BufferData[PUSHBUFFER_NELEMS];
  50. public:
  51. PushBuffer(void)
  52. {
  53. m_State = PUSHBUFFER_AVAILABLE;
  54. }
  55. };
  56. // When running multithreaded, lock for write calls actually return a pointer to temporary memory
  57. // buffer. When the buffer is later unlocked by the caller, data must be queued with the Unlock()
  58. // that lets the d3d thread know how much data to copy from where. One possible optimization for
  59. // things which write a lot of data into lock buffers woudl be to proviude a way for the caller to
  60. // occasionally check if the Lock() has been dequeued. If so, the the data pushed so far could be
  61. // copied asynchronously into the buffer, while the caller would be told to switch to writing
  62. // directly to the vertex buffer.
  63. //
  64. // another possibility would be lock()ing in advance for large ones, such as the world renderer,
  65. // or keeping multiple locked vb's open for meshbuilder.
  66. struct LockedBufferContext
  67. {
  68. PushBuffer *m_pPushBuffer; // if a push buffer was used to hold
  69. // the temporary data, this will be non-null
  70. void *m_pMallocedMemory; // if memory had to be malloc'd, this will be set.
  71. size_t m_MallocSize; // # of bytes malloced if mallocedmem ptr non-null
  72. LockedBufferContext( void )
  73. {
  74. m_pPushBuffer = NULL;
  75. m_pMallocedMemory = NULL;
  76. }
  77. };
  78. // push buffer commands follow
  79. enum PushBufferCommand
  80. {
  81. PBCMD_END, // at end of push buffer
  82. PBCMD_SET_RENDERSTATE, // state, val
  83. PBCMD_SET_RENDERSTATEINLINE, // state, val
  84. PBCMD_SET_TEXTURE, // stage, txtr
  85. PBCMD_DRAWPRIM, // prim type, start v, nprims
  86. PBCMD_DRAWPRIMUP_RESZ, // special RESZ resolve drawPrimUP
  87. PBCMD_DRAWINDEXEDPRIM, // prim type, baseidx, minidx, numv, starti, pcount
  88. PBCMD_SET_PIXEL_SHADER, // shaderptr
  89. PBCMD_SET_VERTEX_SHADER, // shaderptr
  90. PBCMD_SET_PIXEL_SHADER_CONSTANT, // startreg, nregs, data...
  91. PBCMD_SET_BOOLEAN_PIXEL_SHADER_CONSTANT, // startreg, nregs, data...
  92. PBCMD_SET_INTEGER_PIXEL_SHADER_CONSTANT, // startreg, nregs, data...
  93. PBCMD_SET_MAX_USED_VERTEX_SHADER_CONSTANTS_HINT, // nMaxReg
  94. PBCMD_SET_VERTEX_SHADER_CONSTANT, // startreg, nregs, data...
  95. PBCMD_SET_BOOLEAN_VERTEX_SHADER_CONSTANT, // startreg, nregs, data...
  96. PBCMD_SET_INTEGER_VERTEX_SHADER_CONSTANT, // startreg, nregs, data...
  97. PBCMD_SET_RENDER_TARGET, // idx, targetptr
  98. PBCMD_SET_DEPTH_STENCIL_SURFACE, // surfptr
  99. PBCMD_SET_STREAM_SOURCE, // idx, sptr, ofs, stride
  100. PBCMD_SET_INDICES, // idxbuffer
  101. PBCMD_SET_SAMPLER_STATE, // stage, state, val
  102. PBCMD_SET_SAMPLER_STATES, // Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter
  103. PBCMD_UNLOCK_VB, // vptr
  104. PBCMD_UNLOCK_ACTAULSIZE_VB, // vptr, actualsize
  105. PBCMD_UNLOCK_IB, // idxbufptr
  106. PBCMD_UNLOCK_ACTAULSIZE_IB, // idxbufptr, actualsize
  107. PBCMD_SETVIEWPORT, // vp_struct
  108. PBCMD_CLEAR, // count, n rect structs, flags, color, z, stencil
  109. PBCMD_SET_VERTEXDECLARATION, // vdeclptr
  110. PBCMD_BEGIN_SCENE, //
  111. PBCMD_END_SCENE, //
  112. PBCMD_PRESENT, // complicated..see code
  113. PBCMD_SETCLIPPLANE, // idx, 4 floats
  114. PBCMD_STRETCHRECT, // see code
  115. PBCMD_STRETCHRECT_NVAPI, // see code
  116. PBCMD_ASYNC_LOCK_VB, // see code
  117. PBCMD_ASYNC_UNLOCK_VB,
  118. PBCMD_ASYNC_LOCK_IB, // see code
  119. PBCMD_ASYNC_UNLOCK_IB,
  120. PBCMD_SET_SCISSOR_RECT, // RECT
  121. PBCMD_ACQUIRE_THREAD_OWNERSHIP,
  122. PBCMD_RELEASE_THREAD_OWNERSHIP
  123. };
  124. #define N_DWORDS( x ) ( ( sizeof( x ) + sizeof( DWORD ) - 1 ) / sizeof( DWORD ) )
  125. #define N_DWORDS_IN_PTR ( N_DWORDS( void * ) )
  126. class D3DDeviceWrapper
  127. {
  128. private:
  129. IDirect3DDevice9 *m_pD3DDevice;
  130. D3DPRESENT_PARAMETERS *m_pPresentParameters;
  131. void *m_pHWnd;
  132. bool m_bSupportsTessellation;
  133. int m_nCurrentTessLevel;
  134. TessellationMode_t m_nTessellationMode;
  135. #if SHADERAPI_USE_SMP
  136. ThreadHandle_t m_pASyncThreadHandle;
  137. PushBuffer *m_pCurPushBuffer;
  138. uint32 *m_pOutputPtr;
  139. size_t m_PushBufferFreeSlots;
  140. #endif
  141. #if ( IS_WINDOWS_PC ) && !NO_STEREO_D3D9
  142. nv::stereo::HL2StereoD3D9 *m_pStereoTexUpdater;
  143. #endif
  144. #if SHADERAPI_BUFFER_D3DCALLS
  145. bool m_bBufferingD3DCalls;
  146. # define SHADERAPI_BUFFER_MAXRENDERTARGETS 4
  147. IDirect3DSurface9 *m_StoredRenderTargets[SHADERAPI_BUFFER_MAXRENDERTARGETS];
  148. #endif
  149. PushBuffer *FindFreePushBuffer( PushBufferState newstate ); // find a free push buffer and change its state
  150. void GetPushBuffer(void); // set us up to point at a new push buffer
  151. void SubmitPushBufferAndGetANewOne(void); // submit the current push buffer
  152. void ExecutePushBuffer( PushBuffer const *pb);
  153. #if SHADERAPI_USE_SMP
  154. void Synchronize(void); // wait for all commands to be done
  155. #else
  156. FORCEINLINE void Synchronize(void)
  157. {
  158. }
  159. #endif
  160. void SubmitIfNotBusy(void);
  161. template<class T> FORCEINLINE void PushStruct( PushBufferCommand cmd, T const *str )
  162. {
  163. int nwords=N_DWORDS( T );
  164. AllocatePushBufferSpace( 1+ nwords );
  165. m_pOutputPtr[0]=cmd;
  166. memcpy( m_pOutputPtr+1, str, sizeof( T ) );
  167. m_pOutputPtr += 1+nwords;
  168. }
  169. FORCEINLINE void AllocatePushBufferSpace(size_t nSlots)
  170. {
  171. // check for N slots of space, and decrement amount of space left
  172. if ( nSlots>m_PushBufferFreeSlots ) // out of room?
  173. {
  174. SubmitPushBufferAndGetANewOne();
  175. }
  176. m_PushBufferFreeSlots -= nSlots;
  177. }
  178. // simple methods for pushing a few words into output buffer
  179. FORCEINLINE void Push( PushBufferCommand cmd )
  180. {
  181. AllocatePushBufferSpace(1);
  182. m_pOutputPtr[0]=cmd;
  183. m_pOutputPtr++;
  184. }
  185. FORCEINLINE void Push( PushBufferCommand cmd, int arg1)
  186. {
  187. AllocatePushBufferSpace(2);
  188. m_pOutputPtr[0]=cmd;
  189. m_pOutputPtr[1]=arg1;
  190. m_pOutputPtr += 2;
  191. }
  192. FORCEINLINE void Push( PushBufferCommand cmd, void *ptr )
  193. {
  194. AllocatePushBufferSpace(1+N_DWORDS_IN_PTR);
  195. *(m_pOutputPtr++)=cmd;
  196. *((void **) m_pOutputPtr)=ptr;
  197. m_pOutputPtr+=N_DWORDS_IN_PTR;
  198. }
  199. FORCEINLINE void Push( PushBufferCommand cmd, void *ptr, void *ptr1 )
  200. {
  201. AllocatePushBufferSpace(1+2*N_DWORDS_IN_PTR);
  202. *(m_pOutputPtr++)=cmd;
  203. *((void **) m_pOutputPtr)=ptr;
  204. m_pOutputPtr+=N_DWORDS_IN_PTR;
  205. *((void **) m_pOutputPtr)=ptr1;
  206. m_pOutputPtr+=N_DWORDS_IN_PTR;
  207. }
  208. FORCEINLINE void Push( PushBufferCommand cmd, void *arg1, uint32 arg2, uint32 arg3, uint32 arg4,
  209. void *arg5)
  210. {
  211. AllocatePushBufferSpace(1+N_DWORDS_IN_PTR+1+1+1+N_DWORDS_IN_PTR);
  212. *(m_pOutputPtr++)=cmd;
  213. *((void **) m_pOutputPtr)=arg1;
  214. m_pOutputPtr+=N_DWORDS_IN_PTR;
  215. *(m_pOutputPtr++)=arg2;
  216. *(m_pOutputPtr++)=arg3;
  217. *(m_pOutputPtr++)=arg4;
  218. *((void **) m_pOutputPtr)=arg5;
  219. m_pOutputPtr+=N_DWORDS_IN_PTR;
  220. }
  221. FORCEINLINE void Push( PushBufferCommand cmd, void *ptr, uint32 arg1 )
  222. {
  223. AllocatePushBufferSpace( 1 + N_DWORDS_IN_PTR + 1 );
  224. *(m_pOutputPtr++) = cmd;
  225. *((void **)m_pOutputPtr) = ptr;
  226. m_pOutputPtr += N_DWORDS_IN_PTR;
  227. *(m_pOutputPtr++) = arg1;
  228. }
  229. FORCEINLINE void Push( PushBufferCommand cmd, uint32 arg1, void *ptr )
  230. {
  231. AllocatePushBufferSpace(2+N_DWORDS_IN_PTR);
  232. *(m_pOutputPtr++)=cmd;
  233. *(m_pOutputPtr++)=arg1;
  234. *((void **) m_pOutputPtr)=ptr;
  235. m_pOutputPtr+=N_DWORDS_IN_PTR;
  236. }
  237. FORCEINLINE void Push( PushBufferCommand cmd, uint32 arg1, void *ptr, int arg2, int arg3 )
  238. {
  239. AllocatePushBufferSpace( 4+N_DWORDS_IN_PTR );
  240. *(m_pOutputPtr++)=cmd;
  241. *(m_pOutputPtr++)=arg1;
  242. *((void **) m_pOutputPtr)=ptr;
  243. m_pOutputPtr+=N_DWORDS_IN_PTR;
  244. m_pOutputPtr[0]=arg2;
  245. m_pOutputPtr[1]=arg3;
  246. m_pOutputPtr += 2;
  247. }
  248. FORCEINLINE void Push( PushBufferCommand cmd, int arg1, int arg2)
  249. {
  250. AllocatePushBufferSpace(3);
  251. m_pOutputPtr[0]=cmd;
  252. m_pOutputPtr[1]=arg1;
  253. m_pOutputPtr[2]=arg2;
  254. m_pOutputPtr += 3;
  255. }
  256. FORCEINLINE void Push( PushBufferCommand cmd, int arg1, int arg2, int arg3)
  257. {
  258. AllocatePushBufferSpace(4);
  259. m_pOutputPtr[0]=cmd;
  260. m_pOutputPtr[1]=arg1;
  261. m_pOutputPtr[2]=arg2;
  262. m_pOutputPtr[3]=arg3;
  263. m_pOutputPtr += 4;
  264. }
  265. FORCEINLINE void Push( PushBufferCommand cmd, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6 )
  266. {
  267. AllocatePushBufferSpace(7);
  268. m_pOutputPtr[0]=cmd;
  269. m_pOutputPtr[1]=arg1;
  270. m_pOutputPtr[2]=arg2;
  271. m_pOutputPtr[3]=arg3;
  272. m_pOutputPtr[4]=arg4;
  273. m_pOutputPtr[5]=arg5;
  274. m_pOutputPtr[6]=arg6;
  275. m_pOutputPtr += 7;
  276. }
  277. FORCEINLINE void Push( PushBufferCommand cmd, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7 )
  278. {
  279. AllocatePushBufferSpace( 8 );
  280. m_pOutputPtr[0]=cmd;
  281. m_pOutputPtr[1]=arg1;
  282. m_pOutputPtr[2] = arg2;
  283. m_pOutputPtr[3] = arg3;
  284. m_pOutputPtr[4] = arg4;
  285. m_pOutputPtr[5] = arg5;
  286. m_pOutputPtr[6] = arg6;
  287. m_pOutputPtr[7] = arg7;
  288. m_pOutputPtr += 8;
  289. }
  290. FORCEINLINE bool ASyncMode(void) const
  291. {
  292. #if SHADERAPI_USE_SMP
  293. # if SHADERAPI_BUFFER_D3DCALLS
  294. return m_bBufferingD3DCalls;
  295. # else
  296. return (m_pASyncThreadHandle != 0 );
  297. # endif
  298. #else
  299. return false;
  300. #endif
  301. }
  302. FORCEINLINE IDirect3DDevice9* Dx9Device(void) const
  303. {
  304. return m_pD3DDevice;
  305. }
  306. void AsynchronousLock( IDirect3DVertexBuffer9* vb, size_t offset, size_t size, void **ptr,
  307. DWORD flags,
  308. LockedBufferContext *lb);
  309. void AsynchronousLock( IDirect3DIndexBuffer9* ib, size_t offset, size_t size, void **ptr,
  310. DWORD flags,
  311. LockedBufferContext *lb);
  312. // handlers for push buffer contexts
  313. void HandleAsynchronousLockVBCommand( uint32 const *dptr );
  314. void HandleAsynchronousUnLockVBCommand( uint32 const *dptr );
  315. void HandleAsynchronousLockIBCommand( uint32 const *dptr );
  316. void HandleAsynchronousUnLockIBCommand( uint32 const *dptr );
  317. public:
  318. D3DDeviceWrapper()
  319. #if ( IS_WINDOWS_PC ) && !NO_STEREO_D3D9
  320. : m_pStereoTexUpdater( 0 )
  321. #endif
  322. { }
  323. ~D3DDeviceWrapper()
  324. {
  325. #if ( IS_WINDOWS_PC ) && !NO_STEREO_D3D9
  326. delete m_pStereoTexUpdater;
  327. #endif
  328. }
  329. void UpdateStereoTexture( IDirect3DTexture9 *pTex, bool devLost, bool *pStereoActiveThisFrame );
  330. bool IsStereoSupported() const
  331. {
  332. #if ( IS_WINDOWS_PC ) && !NO_STEREO_D3D9
  333. // NOTE: This is slow! Can take more than 1 ms!
  334. return nv::stereo::IsStereoEnabled();
  335. #else
  336. return false;
  337. #endif
  338. }
  339. bool IsStereoActivated() const
  340. {
  341. #if ( IS_WINDOWS_PC ) && !NO_STEREO_D3D9
  342. return m_pStereoTexUpdater && m_pStereoTexUpdater->IsStereoActive();
  343. #else
  344. return false;
  345. #endif
  346. }
  347. #if ( IS_WINDOWS_PC ) && !NO_STEREO_D3D9
  348. void SetStereoTextureUpdater( nv::stereo::HL2StereoD3D9 *pStereoTexUpdater )
  349. {
  350. m_pStereoTexUpdater = pStereoTexUpdater;
  351. }
  352. #endif
  353. #if SHADERAPI_BUFFER_D3DCALLS
  354. void ExecuteAllWork( void );
  355. #endif
  356. void RunThread( void ); // this is what the worker thread runs
  357. void SetASyncMode( bool onoff );
  358. bool IsActive( void )const
  359. {
  360. return m_pD3DDevice != NULL;
  361. }
  362. void D3DeviceWrapper(void)
  363. {
  364. m_pD3DDevice = 0;
  365. m_pPresentParameters = 0;
  366. m_pHWnd = 0;
  367. #if SHADERAPI_USE_SMP
  368. m_pASyncThreadHandle = 0;
  369. #endif
  370. #if SHADERAPI_BUFFER_D3DCALLS
  371. m_bBufferingD3DCalls = false;
  372. #endif
  373. }
  374. void SetDevicePtr( IDirect3DDevice9 *pD3DDev, D3DPRESENT_PARAMETERS *pPresentParameters, void *pHWnd )
  375. {
  376. m_pD3DDevice = pD3DDev;
  377. m_pPresentParameters = pPresentParameters;
  378. m_pHWnd = pHWnd;
  379. }
  380. void ReportDeviceReset( void )
  381. {
  382. g_pShaderDeviceMgr->InvokeDeviceResetNotifications( m_pD3DDevice, m_pPresentParameters, m_pHWnd );
  383. }
  384. void SetSupportsTessellation( bool bSupportsTessellation )
  385. {
  386. m_bSupportsTessellation = bSupportsTessellation;
  387. }
  388. void ShutDownDevice(void)
  389. {
  390. if ( ASyncMode() )
  391. {
  392. // sync w/ thread
  393. }
  394. m_pD3DDevice = 0;
  395. m_pPresentParameters = 0;
  396. m_pHWnd = 0;
  397. }
  398. void FORCEINLINE SetDepthStencilSurface( IDirect3DSurface9 *new_stencil )
  399. {
  400. if ( ASyncMode() )
  401. Push( PBCMD_SET_DEPTH_STENCIL_SURFACE, new_stencil );
  402. else
  403. DO_D3D( SetDepthStencilSurface( new_stencil ) );
  404. }
  405. HRESULT CreateCubeTexture(
  406. UINT EdgeLength,
  407. UINT Levels,
  408. DWORD Usage,
  409. D3DFORMAT Format,
  410. D3DPOOL Pool,
  411. IDirect3DCubeTexture9 ** ppCubeTexture,
  412. HANDLE* pSharedHandle,
  413. char *debugLabel = NULL // <-- OK to not pass this arg, only passed through on opengl
  414. )
  415. {
  416. Synchronize();
  417. return m_pD3DDevice->CreateCubeTexture( EdgeLength, Levels, Usage, Format, Pool,
  418. ppCubeTexture, pSharedHandle
  419. #if PLATFORM_OPENGL
  420. ,debugLabel
  421. #endif
  422. );
  423. }
  424. HRESULT CreateVolumeTexture(
  425. UINT Width,
  426. UINT Height,
  427. UINT Depth,
  428. UINT Levels,
  429. DWORD Usage,
  430. D3DFORMAT Format,
  431. D3DPOOL Pool,
  432. IDirect3DVolumeTexture9** ppVolumeTexture,
  433. HANDLE* pSharedHandle,
  434. char *debugLabel = NULL // <-- OK to not pass this arg, only passed through on opengl
  435. )
  436. {
  437. Synchronize();
  438. return m_pD3DDevice->CreateVolumeTexture( Width, Height, Depth, Levels,
  439. Usage, Format, Pool, ppVolumeTexture,
  440. pSharedHandle
  441. #if PLATFORM_OPENGL
  442. ,debugLabel
  443. #endif
  444. );
  445. }
  446. HRESULT CreateOffscreenPlainSurface( UINT Width,
  447. UINT Height,
  448. D3DFORMAT Format,
  449. D3DPOOL Pool,
  450. IDirect3DSurface9** ppSurface,
  451. HANDLE* pSharedHandle)
  452. {
  453. Synchronize();
  454. return m_pD3DDevice->CreateOffscreenPlainSurface( Width, Height, Format, Pool,
  455. ppSurface, pSharedHandle);
  456. }
  457. HRESULT CreateTexture(
  458. UINT Width,
  459. UINT Height,
  460. UINT Levels,
  461. DWORD Usage,
  462. D3DFORMAT Format,
  463. D3DPOOL Pool,
  464. IDirect3DTexture9** ppTexture,
  465. HANDLE* pSharedHandle,
  466. char *debugLabel = NULL // <-- OK to not pass this arg, only passed through on opengl
  467. )
  468. {
  469. Synchronize();
  470. return m_pD3DDevice->CreateTexture( Width, Height, Levels, Usage,
  471. Format, Pool, ppTexture, pSharedHandle
  472. #if PLATFORM_OPENGL
  473. ,debugLabel
  474. #endif
  475. );
  476. }
  477. HRESULT GetRenderTargetData(
  478. IDirect3DSurface9* pRenderTarget,
  479. IDirect3DSurface9* pDestSurface
  480. )
  481. {
  482. Synchronize();
  483. return m_pD3DDevice->GetRenderTargetData( pRenderTarget, pDestSurface );
  484. }
  485. void GetDeviceCaps( D3DCAPS9 * pCaps )
  486. {
  487. Synchronize();
  488. m_pD3DDevice->GetDeviceCaps( pCaps );
  489. }
  490. LPCSTR GetPixelShaderProfile( void )
  491. {
  492. Synchronize();
  493. return D3DXGetPixelShaderProfile( m_pD3DDevice );
  494. }
  495. HRESULT TestCooperativeLevel( void )
  496. {
  497. // hack! We are going to assume that calling this immediately when in buffered mode isn't going to cause problems.
  498. #if !SHADERAPI_BUFFER_D3DCALLS
  499. Synchronize();
  500. #endif
  501. return m_pD3DDevice->TestCooperativeLevel();
  502. }
  503. HRESULT GetFrontBufferData( UINT iSwapChain, IDirect3DSurface9 * pDestSurface )
  504. {
  505. Synchronize();
  506. return m_pD3DDevice->GetFrontBufferData( iSwapChain, pDestSurface );
  507. }
  508. void SetGammaRamp( int swapchain, int flags, D3DGAMMARAMP const *pRamp)
  509. {
  510. Synchronize();
  511. m_pD3DDevice->SetGammaRamp( swapchain, flags, pRamp);
  512. }
  513. HRESULT GetTexture( DWORD Stage, IDirect3DBaseTexture9 ** ppTexture )
  514. {
  515. Synchronize();
  516. return m_pD3DDevice->GetTexture( Stage, ppTexture );
  517. }
  518. HRESULT GetFVF( DWORD * pFVF )
  519. {
  520. Synchronize();
  521. return m_pD3DDevice->GetFVF( pFVF );
  522. }
  523. HRESULT GetDepthStencilSurface(
  524. IDirect3DSurface9 ** ppZStencilSurface
  525. )
  526. {
  527. Synchronize();
  528. return m_pD3DDevice->GetDepthStencilSurface( ppZStencilSurface );
  529. }
  530. FORCEINLINE void SetClipPlane( int idx, float const * pplane)
  531. {
  532. RECORD_COMMAND( DX8_SET_CLIP_PLANE, 5 );
  533. RECORD_INT( idx );
  534. RECORD_FLOAT( pplane[0] );
  535. RECORD_FLOAT( pplane[1] );
  536. RECORD_FLOAT( pplane[2] );
  537. RECORD_FLOAT( pplane[3] );
  538. if ( ASyncMode() )
  539. {
  540. AllocatePushBufferSpace( 6 );
  541. m_pOutputPtr[0]=PBCMD_SETCLIPPLANE;
  542. m_pOutputPtr[1]=idx;
  543. memcpy(m_pOutputPtr+2,pplane, 4*sizeof(float) );
  544. m_pOutputPtr += 6;
  545. }
  546. else
  547. DO_D3D( SetClipPlane( idx, pplane ) );
  548. }
  549. FORCEINLINE void SetVertexDeclaration( IDirect3DVertexDeclaration9 *decl )
  550. {
  551. RECORD_COMMAND( DX8_SET_VERTEX_DECLARATION, 1 );
  552. RECORD_INT( ( int ) decl );
  553. if ( ASyncMode() )
  554. {
  555. Push( PBCMD_SET_VERTEXDECLARATION, decl );
  556. }
  557. else
  558. DO_D3D( SetVertexDeclaration( decl ) );
  559. }
  560. FORCEINLINE void SetViewport( D3DVIEWPORT9 const *vp )
  561. {
  562. RECORD_COMMAND( DX8_SET_VIEWPORT, 1 );
  563. RECORD_STRUCT( vp, sizeof( *vp ));
  564. if ( ASyncMode() )
  565. PushStruct( PBCMD_SETVIEWPORT, vp );
  566. else
  567. DO_D3D( SetViewport( vp ) );
  568. }
  569. HRESULT GetRenderTarget(
  570. DWORD RenderTargetIndex,
  571. IDirect3DSurface9 ** ppRenderTarget)
  572. {
  573. #if SHADERAPI_BUFFER_D3DCALLS
  574. if ( ASyncMode() )
  575. {
  576. Assert( RenderTargetIndex >= 0 && RenderTargetIndex < SHADERAPI_BUFFER_MAXRENDERTARGETS );
  577. *ppRenderTarget = m_StoredRenderTargets[RenderTargetIndex];
  578. return D3D_OK;
  579. }
  580. #endif
  581. Synchronize();
  582. return m_pD3DDevice->GetRenderTarget( RenderTargetIndex, ppRenderTarget );
  583. }
  584. HRESULT CreateQuery( D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery )
  585. {
  586. Synchronize();
  587. return m_pD3DDevice->CreateQuery( Type, ppQuery );
  588. }
  589. HRESULT CreateRenderTarget(
  590. UINT Width,
  591. UINT Height,
  592. D3DFORMAT Format,
  593. D3DMULTISAMPLE_TYPE MultiSample,
  594. DWORD MultisampleQuality,
  595. BOOL Lockable,
  596. IDirect3DSurface9** ppSurface,
  597. HANDLE* pSharedHandle
  598. )
  599. {
  600. Synchronize();
  601. return m_pD3DDevice->CreateRenderTarget( Width, Height, Format, MultiSample,
  602. MultisampleQuality, Lockable, ppSurface,
  603. pSharedHandle);
  604. }
  605. HRESULT CreateDepthStencilSurface(
  606. UINT Width,
  607. UINT Height,
  608. D3DFORMAT Format,
  609. D3DMULTISAMPLE_TYPE MultiSample,
  610. DWORD MultisampleQuality,
  611. BOOL Discard,
  612. IDirect3DSurface9** ppSurface,
  613. HANDLE* pSharedHandle
  614. )
  615. {
  616. Synchronize();
  617. return m_pD3DDevice->CreateDepthStencilSurface( Width, Height, Format, MultiSample,
  618. MultisampleQuality, Discard, ppSurface,
  619. pSharedHandle );
  620. }
  621. FORCEINLINE void SetRenderTarget( int idx, IDirect3DSurface9 *new_rt )
  622. {
  623. if (ASyncMode())
  624. {
  625. Push( PBCMD_SET_RENDER_TARGET, idx, new_rt );
  626. #if SHADERAPI_BUFFER_D3DCALLS
  627. m_StoredRenderTargets[idx] = new_rt;
  628. #endif
  629. }
  630. else
  631. {
  632. // NOTE: If the debug runtime breaks here on the shadow depth render target that is normal. dx9 doesn't directly support shadow
  633. // depth texturing so we are forced to initialize this texture without the render target flagr
  634. DO_D3D( SetRenderTarget( idx, new_rt) );
  635. }
  636. }
  637. FORCEINLINE void LightEnable( int lidx, bool onoff )
  638. {
  639. RECORD_COMMAND( DX8_LIGHT_ENABLE, 2 );
  640. RECORD_INT( lidx );
  641. RECORD_INT( onoff );
  642. Synchronize();
  643. DO_D3D( LightEnable( lidx, onoff ) );
  644. }
  645. FORCEINLINE void SetRenderState( D3DRENDERSTATETYPE state, DWORD val )
  646. {
  647. // Assert( state >= 0 && state < MAX_NUM_RENDERSTATES );
  648. RECORD_RENDER_STATE( state, val );
  649. if (ASyncMode())
  650. {
  651. Push( PBCMD_SET_RENDERSTATE, state, val );
  652. }
  653. else
  654. DO_D3D( SetRenderState( state, val ) );
  655. }
  656. #ifdef DX_TO_GL_ABSTRACTION
  657. FORCEINLINE void SetRenderStateInline( D3DRENDERSTATETYPE state, DWORD val )
  658. {
  659. // Assert( state >= 0 && state < MAX_NUM_RENDERSTATES );
  660. RECORD_RENDER_STATE( state, val );
  661. if (ASyncMode())
  662. {
  663. Push( PBCMD_SET_RENDERSTATEINLINE, state, val );
  664. }
  665. else
  666. DO_D3D( SetRenderStateInline( state, val ) );
  667. }
  668. #endif
  669. FORCEINLINE void SetScissorRect( const RECT *pScissorRect )
  670. {
  671. RECORD_COMMAND( DX8_SET_SCISSOR_RECT, 1 );
  672. RECORD_STRUCT( pScissorRect, 4 * sizeof(LONG) );
  673. if ( ASyncMode() )
  674. {
  675. AllocatePushBufferSpace( 5 );
  676. m_pOutputPtr[0] = PBCMD_SET_SCISSOR_RECT;
  677. memcpy( m_pOutputPtr + 1, pScissorRect, sizeof( *pScissorRect ) );
  678. }
  679. else
  680. DO_D3D( SetScissorRect( pScissorRect ) );
  681. }
  682. #ifdef DX_TO_GL_ABSTRACTION
  683. FORCEINLINE void SetMaxUsedVertexShaderConstantsHint( uint nMaxReg )
  684. {
  685. if (ASyncMode())
  686. Push( PBCMD_SET_MAX_USED_VERTEX_SHADER_CONSTANTS_HINT, nMaxReg );
  687. else
  688. DO_D3D( SetMaxUsedVertexShaderConstantsHint( nMaxReg ) );
  689. }
  690. #endif
  691. FORCEINLINE void SetVertexShaderConstantF( UINT StartRegister, CONST float * pConstantData,
  692. UINT Vector4fCount)
  693. {
  694. RECORD_COMMAND( DX8_SET_VERTEX_SHADER_CONSTANT, 3 );
  695. RECORD_INT( StartRegister );
  696. RECORD_INT( Vector4fCount );
  697. RECORD_STRUCT( pConstantData, Vector4fCount * 4 * sizeof(float) );
  698. if ( ASyncMode() )
  699. {
  700. AllocatePushBufferSpace(3+4*Vector4fCount);
  701. m_pOutputPtr[0]=PBCMD_SET_VERTEX_SHADER_CONSTANT;
  702. m_pOutputPtr[1]=StartRegister;
  703. m_pOutputPtr[2]=Vector4fCount;
  704. memcpy(m_pOutputPtr+3,pConstantData,sizeof(float)*4*Vector4fCount);
  705. m_pOutputPtr+=3+4*Vector4fCount;
  706. }
  707. else
  708. DO_D3D( SetVertexShaderConstantF( StartRegister, pConstantData, Vector4fCount ) );
  709. }
  710. FORCEINLINE void SetVertexShaderConstantB( UINT StartRegister, CONST int * pConstantData,
  711. UINT BoolCount)
  712. {
  713. RECORD_COMMAND( DX8_SET_VERTEX_SHADER_CONSTANT, 3 );
  714. RECORD_INT( StartRegister );
  715. RECORD_INT( BoolCount );
  716. RECORD_STRUCT( pConstantData, BoolCount * sizeof(int) );
  717. if ( ASyncMode() )
  718. {
  719. AllocatePushBufferSpace(3+BoolCount);
  720. m_pOutputPtr[0]=PBCMD_SET_BOOLEAN_VERTEX_SHADER_CONSTANT;
  721. m_pOutputPtr[1]=StartRegister;
  722. m_pOutputPtr[2]=BoolCount;
  723. memcpy(m_pOutputPtr+3,pConstantData,sizeof(int)*BoolCount);
  724. m_pOutputPtr+=3+BoolCount;
  725. }
  726. else
  727. DO_D3D( SetVertexShaderConstantB( StartRegister, pConstantData, BoolCount ) );
  728. }
  729. FORCEINLINE void SetVertexShaderConstantI( UINT StartRegister, CONST int * pConstantData,
  730. UINT Vector4IntCount)
  731. {
  732. RECORD_COMMAND( DX8_SET_VERTEX_SHADER_CONSTANT, 3 );
  733. RECORD_INT( StartRegister );
  734. RECORD_INT( Vector4IntCount );
  735. RECORD_STRUCT( pConstantData, Vector4IntCount * 4 * sizeof(int) );
  736. if ( ASyncMode() )
  737. {
  738. AllocatePushBufferSpace(3+4*Vector4IntCount);
  739. m_pOutputPtr[0]=PBCMD_SET_INTEGER_VERTEX_SHADER_CONSTANT;
  740. m_pOutputPtr[1]=StartRegister;
  741. m_pOutputPtr[2]=Vector4IntCount;
  742. memcpy(m_pOutputPtr+3,pConstantData,sizeof(int)*4*Vector4IntCount);
  743. m_pOutputPtr+=3+4*Vector4IntCount;
  744. }
  745. else
  746. DO_D3D( SetVertexShaderConstantI( StartRegister, pConstantData, Vector4IntCount ) );
  747. }
  748. FORCEINLINE void SetPixelShaderConstantF( UINT StartRegister, CONST float * pConstantData,
  749. UINT Vector4fCount)
  750. {
  751. RECORD_COMMAND( DX8_SET_PIXEL_SHADER_CONSTANT, 3 );
  752. RECORD_INT( StartRegister );
  753. RECORD_INT( Vector4fCount );
  754. RECORD_STRUCT( pConstantData, Vector4fCount * 4 * sizeof(float) );
  755. if ( ASyncMode() )
  756. {
  757. AllocatePushBufferSpace(3+4*Vector4fCount);
  758. m_pOutputPtr[0]=PBCMD_SET_PIXEL_SHADER_CONSTANT;
  759. m_pOutputPtr[1]=StartRegister;
  760. m_pOutputPtr[2]=Vector4fCount;
  761. memcpy(m_pOutputPtr+3,pConstantData,sizeof(float)*4*Vector4fCount);
  762. m_pOutputPtr+=3+4*Vector4fCount;
  763. }
  764. else
  765. DO_D3D( SetPixelShaderConstantF( StartRegister, pConstantData, Vector4fCount ) );
  766. }
  767. FORCEINLINE void SetPixelShaderConstantB( UINT StartRegister, CONST int * pConstantData,
  768. UINT BoolCount)
  769. {
  770. RECORD_COMMAND( DX8_SET_PIXEL_SHADER_CONSTANT, 3 );
  771. RECORD_INT( StartRegister );
  772. RECORD_INT( BoolCount );
  773. RECORD_STRUCT( pConstantData, BoolCount * sizeof(int) );
  774. if ( ASyncMode() )
  775. {
  776. AllocatePushBufferSpace(3+BoolCount);
  777. m_pOutputPtr[0]=PBCMD_SET_BOOLEAN_PIXEL_SHADER_CONSTANT;
  778. m_pOutputPtr[1]=StartRegister;
  779. m_pOutputPtr[2]=BoolCount;
  780. memcpy(m_pOutputPtr+3,pConstantData,sizeof(int)*BoolCount);
  781. m_pOutputPtr+=3+BoolCount;
  782. }
  783. else
  784. DO_D3D( SetPixelShaderConstantB( StartRegister, pConstantData, BoolCount ) );
  785. }
  786. FORCEINLINE void SetPixelShaderConstantI( UINT StartRegister, CONST int * pConstantData,
  787. UINT Vector4IntCount)
  788. {
  789. RECORD_COMMAND( DX8_SET_PIXEL_SHADER_CONSTANT, 3 );
  790. RECORD_INT( StartRegister );
  791. RECORD_INT( Vector4IntCount );
  792. RECORD_STRUCT( pConstantData, Vector4IntCount * 4 * sizeof(int) );
  793. if ( ASyncMode() )
  794. {
  795. AllocatePushBufferSpace(3+4*Vector4IntCount);
  796. m_pOutputPtr[0]=PBCMD_SET_INTEGER_PIXEL_SHADER_CONSTANT;
  797. m_pOutputPtr[1]=StartRegister;
  798. m_pOutputPtr[2]=Vector4IntCount;
  799. memcpy(m_pOutputPtr+3,pConstantData,sizeof(int)*4*Vector4IntCount);
  800. m_pOutputPtr+=3+4*Vector4IntCount;
  801. }
  802. else
  803. DO_D3D( SetPixelShaderConstantI( StartRegister, pConstantData, Vector4IntCount ) );
  804. }
  805. HRESULT StretchRect( IDirect3DSurface9 * pSourceSurface,
  806. CONST RECT * pSourceRect,
  807. IDirect3DSurface9 * pDestSurface,
  808. CONST RECT * pDestRect,
  809. D3DTEXTUREFILTERTYPE Filter )
  810. {
  811. if ( ASyncMode() )
  812. {
  813. AllocatePushBufferSpace(1 + ( 2 * N_DWORDS_IN_PTR ) + N_DWORDS( RECT ) + ( 2 * N_DWORDS_IN_PTR ) + N_DWORDS( RECT ) + 1);
  814. *(m_pOutputPtr++)=PBCMD_STRETCHRECT;
  815. *(IDirect3DSurface9**)(m_pOutputPtr) = pSourceSurface;
  816. m_pOutputPtr += N_DWORDS_IN_PTR;
  817. *(m_pOutputPtr++)=(pSourceRect != NULL);
  818. if (pSourceRect)
  819. {
  820. memcpy(m_pOutputPtr,pSourceRect,sizeof(RECT));
  821. }
  822. m_pOutputPtr+=N_DWORDS(RECT);
  823. *(IDirect3DSurface9**)(m_pOutputPtr) = pDestSurface;
  824. m_pOutputPtr += N_DWORDS_IN_PTR;
  825. *(m_pOutputPtr++)=(pDestRect != NULL);
  826. if (pDestRect)
  827. memcpy(m_pOutputPtr,pDestRect,sizeof(RECT));
  828. m_pOutputPtr+=N_DWORDS(RECT);
  829. *(m_pOutputPtr++)=Filter;
  830. return S_OK; // !bug!
  831. }
  832. else
  833. return m_pD3DDevice->
  834. StretchRect( pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter );
  835. }
  836. #ifndef DX_TO_GL_ABSTRACTION
  837. NvAPI_Status StretchRectEx_NvAPI( IDirect3DResource9 *pSourceResource,
  838. CONST RECT * pSourceRect,
  839. IDirect3DResource9 * pDestResource,
  840. CONST RECT * pDestRect,
  841. D3DTEXTUREFILTERTYPE Filter )
  842. {
  843. if ( ASyncMode() )
  844. {
  845. AllocatePushBufferSpace( 1 + 1 + 1 + N_DWORDS( RECT ) + 1 + 1 + N_DWORDS( RECT ) + 1 );
  846. *(m_pOutputPtr++) = PBCMD_STRETCHRECT_NVAPI;
  847. *(m_pOutputPtr++) = (int)pSourceResource;
  848. *(m_pOutputPtr++) = (pSourceRect != NULL);
  849. if ( pSourceRect )
  850. {
  851. memcpy( m_pOutputPtr, pSourceRect, sizeof( RECT ) );
  852. }
  853. m_pOutputPtr += N_DWORDS( RECT );
  854. *(m_pOutputPtr++) = (int)pDestResource;
  855. *(m_pOutputPtr++) = (pDestRect != NULL);
  856. if ( pDestRect )
  857. memcpy( m_pOutputPtr, pDestRect, sizeof( RECT ) );
  858. m_pOutputPtr += N_DWORDS( RECT );
  859. *(m_pOutputPtr++) = Filter;
  860. return NVAPI_OK; // !bug!
  861. }
  862. else
  863. {
  864. TM_ZONE( TELEMETRY_LEVEL1, TMZF_NONE, "NvAPI_D3D9_StretchRectEx" );
  865. NvAPI_Status status = NvAPI_D3D9_StretchRectEx( m_pD3DDevice,
  866. pSourceResource, pSourceRect, pDestResource, pDestRect, Filter );
  867. pSourceResource->Release();
  868. return status;
  869. }
  870. }
  871. #endif
  872. FORCEINLINE void BeginScene(void)
  873. {
  874. RECORD_COMMAND( DX8_BEGIN_SCENE, 0 );
  875. if ( ASyncMode() )
  876. Push( PBCMD_BEGIN_SCENE );
  877. else
  878. DO_D3D( BeginScene() );
  879. }
  880. FORCEINLINE void EndScene(void)
  881. {
  882. RECORD_COMMAND( DX8_END_SCENE, 0 );
  883. if ( ASyncMode() )
  884. Push( PBCMD_END_SCENE );
  885. else
  886. DO_D3D( EndScene() );
  887. }
  888. FORCEINLINE HRESULT Lock( IDirect3DVertexBuffer9* vb, size_t offset, size_t size, void **ptr, DWORD flags )
  889. {
  890. Assert( size ); // lock size of 0 = unknown entire size of buffer = bad
  891. Synchronize();
  892. HRESULT hr = vb->Lock(offset, size, ptr, flags);
  893. switch (hr)
  894. {
  895. case D3DERR_INVALIDCALL:
  896. Warning( "D3DERR_INVALIDCALL - Vertex Buffer Lock Failed in %s on line %d(offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  897. break;
  898. case D3DERR_DRIVERINTERNALERROR:
  899. Warning( "D3DERR_DRIVERINTERNALERROR - Vertex Buffer Lock Failed in %s on line %d (offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  900. break;
  901. case D3DERR_OUTOFVIDEOMEMORY:
  902. Warning( "D3DERR_OUTOFVIDEOMEMORY - Vertex Buffer Lock Failed in %s on line %d (offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  903. break;
  904. }
  905. return hr;
  906. }
  907. FORCEINLINE HRESULT Lock( IDirect3DVertexBuffer9* vb, size_t offset, size_t size, void **ptr,
  908. DWORD flags,
  909. LockedBufferContext *lb)
  910. {
  911. HRESULT hr = D3D_OK;
  912. // asynchronous write-only dynamic vb lock
  913. if ( ASyncMode() )
  914. {
  915. AsynchronousLock( vb, offset, size, ptr, flags, lb );
  916. }
  917. else
  918. {
  919. hr = vb->Lock(offset, size, ptr, flags);
  920. switch (hr)
  921. {
  922. case D3DERR_INVALIDCALL:
  923. Warning( "D3DERR_INVALIDCALL - Vertex Buffer Lock Failed in %s on line %d(offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  924. break;
  925. case D3DERR_DRIVERINTERNALERROR:
  926. Warning( "D3DERR_DRIVERINTERNALERROR - Vertex Buffer Lock Failed in %s on line %d (offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  927. break;
  928. case D3DERR_OUTOFVIDEOMEMORY:
  929. Warning( "D3DERR_OUTOFVIDEOMEMORY - Vertex Buffer Lock Failed in %s on line %d (offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  930. break;
  931. }
  932. }
  933. return hr;
  934. }
  935. FORCEINLINE HRESULT Lock( IDirect3DIndexBuffer9* ib, size_t offset, size_t size, void **ptr, DWORD flags)
  936. {
  937. HRESULT hr = D3D_OK;
  938. Synchronize();
  939. hr = ib->Lock(offset, size, ptr, flags);
  940. switch (hr)
  941. {
  942. case D3DERR_INVALIDCALL:
  943. Warning( "D3DERR_INVALIDCALL - Index Buffer Lock Failed in %s on line %d(offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  944. break;
  945. case D3DERR_DRIVERINTERNALERROR:
  946. Warning( "D3DERR_DRIVERINTERNALERROR - Index Buffer Lock Failed in %s on line %d (offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  947. break;
  948. case D3DERR_OUTOFVIDEOMEMORY:
  949. Warning( "D3DERR_OUTOFVIDEOMEMORY - Index Buffer Lock Failed in %s on line %d (offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  950. break;
  951. }
  952. return hr;
  953. }
  954. // asycnhronous lock of index buffer
  955. FORCEINLINE HRESULT Lock( IDirect3DIndexBuffer9* ib, size_t offset, size_t size, void **ptr, DWORD flags,
  956. LockedBufferContext * lb)
  957. {
  958. HRESULT hr = D3D_OK;
  959. if ( ASyncMode() )
  960. AsynchronousLock( ib, offset, size, ptr, flags, lb );
  961. else
  962. {
  963. hr = ib->Lock(offset, size, ptr, flags);
  964. switch (hr)
  965. {
  966. case D3DERR_INVALIDCALL:
  967. Warning( "D3DERR_INVALIDCALL - Index Buffer Lock Failed in %s on line %d(offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  968. break;
  969. case D3DERR_DRIVERINTERNALERROR:
  970. Warning( "D3DERR_DRIVERINTERNALERROR - Index Buffer Lock Failed in %s on line %d (offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  971. break;
  972. case D3DERR_OUTOFVIDEOMEMORY:
  973. Warning( "D3DERR_OUTOFVIDEOMEMORY - Index Buffer Lock Failed in %s on line %d (offset %d, size %d, flags 0x%x)\n", V_UnqualifiedFileName(__FILE__), __LINE__, (int)offset, (int)size, flags );
  974. break;
  975. }
  976. }
  977. return hr;
  978. }
  979. #ifndef DX_TO_GL_ABSTRACTION
  980. FORCEINLINE HRESULT UpdateSurface( IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST POINT* pDestPoint )
  981. {
  982. return m_pD3DDevice->UpdateSurface( pSourceSurface, pSourceRect, pDestSurface, pDestPoint );
  983. }
  984. #endif
  985. void Release( IDirect3DIndexBuffer9* ib )
  986. {
  987. Synchronize();
  988. ib->Release();
  989. }
  990. void Release( IDirect3DVertexBuffer9* vb )
  991. {
  992. Synchronize();
  993. vb->Release();
  994. }
  995. FORCEINLINE void Unlock( IDirect3DVertexBuffer9* vb )
  996. {
  997. // needed for d3d on pc only
  998. if ( ASyncMode() )
  999. Push(PBCMD_UNLOCK_VB, vb);
  1000. else
  1001. {
  1002. HRESULT hr = vb->Unlock( );
  1003. if ( FAILED(hr) )
  1004. {
  1005. Warning( "Vertex Buffer Unlock Failed in %s on line %d\n", V_UnqualifiedFileName(__FILE__), __LINE__ );
  1006. }
  1007. }
  1008. }
  1009. FORCEINLINE void Unlock( IDirect3DVertexBuffer9* vb, LockedBufferContext *lb, size_t unlock_size)
  1010. {
  1011. // needed for d3d on pc only
  1012. if ( ASyncMode() )
  1013. {
  1014. AllocatePushBufferSpace( 1+N_DWORDS_IN_PTR+N_DWORDS( LockedBufferContext )+1 );
  1015. *(m_pOutputPtr++)=PBCMD_ASYNC_UNLOCK_VB;
  1016. *((IDirect3DVertexBuffer9* *) m_pOutputPtr)=vb;
  1017. m_pOutputPtr+=N_DWORDS_IN_PTR;
  1018. *((LockedBufferContext *) m_pOutputPtr)=*lb;
  1019. m_pOutputPtr+=N_DWORDS( LockedBufferContext );
  1020. *(m_pOutputPtr++)=unlock_size;
  1021. }
  1022. else
  1023. {
  1024. HRESULT hr = vb->Unlock();
  1025. if ( FAILED(hr) )
  1026. {
  1027. Warning( "Vertex Buffer Unlock Failed in %s on line %d\n", V_UnqualifiedFileName(__FILE__), __LINE__ );
  1028. }
  1029. }
  1030. }
  1031. #ifdef DX_TO_GL_ABSTRACTION
  1032. FORCEINLINE void UnlockActualSize( IDirect3DVertexBuffer9* vb, uint nActualSize )
  1033. {
  1034. // needed for d3d on pc only
  1035. if (ASyncMode())
  1036. Push( PBCMD_UNLOCK_ACTAULSIZE_VB, vb, nActualSize );
  1037. else
  1038. {
  1039. vb->UnlockActualSize(nActualSize);
  1040. }
  1041. }
  1042. #endif
  1043. FORCEINLINE void Unlock( IDirect3DIndexBuffer9* ib )
  1044. {
  1045. // needed for d3d on pc only
  1046. if ( ASyncMode() )
  1047. Push(PBCMD_UNLOCK_IB, ib);
  1048. else
  1049. {
  1050. HRESULT hr = ib->Unlock();
  1051. if ( FAILED(hr) )
  1052. {
  1053. Warning( "Index Buffer Unlock Failed in %s on line %d\n", V_UnqualifiedFileName(__FILE__), __LINE__ );
  1054. }
  1055. }
  1056. }
  1057. FORCEINLINE void Unlock( IDirect3DIndexBuffer9* ib, LockedBufferContext *lb, size_t unlock_size)
  1058. {
  1059. // needed for d3d on pc only
  1060. if ( ASyncMode() )
  1061. {
  1062. AllocatePushBufferSpace( 1+N_DWORDS_IN_PTR+N_DWORDS( LockedBufferContext )+1 );
  1063. *(m_pOutputPtr++)=PBCMD_ASYNC_UNLOCK_IB;
  1064. *((IDirect3DIndexBuffer9* *) m_pOutputPtr)=ib;
  1065. m_pOutputPtr+=N_DWORDS_IN_PTR;
  1066. *((LockedBufferContext *) m_pOutputPtr)=*lb;
  1067. m_pOutputPtr+=N_DWORDS( LockedBufferContext );
  1068. *(m_pOutputPtr++)=unlock_size;
  1069. }
  1070. else
  1071. {
  1072. HRESULT hr = ib->Unlock( );
  1073. if ( FAILED(hr) )
  1074. {
  1075. Warning( "Index Buffer Unlock Failed in %s on line %d\n", V_UnqualifiedFileName(__FILE__), __LINE__ );
  1076. }
  1077. }
  1078. }
  1079. #ifdef DX_TO_GL_ABSTRACTION
  1080. FORCEINLINE void UnlockActualSize( IDirect3DIndexBuffer9* ib, uint nActualSize )
  1081. {
  1082. // needed for d3d on pc only
  1083. if (ASyncMode())
  1084. Push( PBCMD_UNLOCK_ACTAULSIZE_IB, ib, nActualSize );
  1085. else
  1086. {
  1087. ib->UnlockActualSize( nActualSize );
  1088. }
  1089. }
  1090. #endif
  1091. void ShowCursor( bool onoff)
  1092. {
  1093. Synchronize();
  1094. DO_D3D( ShowCursor(onoff) );
  1095. }
  1096. FORCEINLINE void Clear( int count, D3DRECT const *pRects, int Flags, D3DCOLOR color, float Z, int stencil)
  1097. {
  1098. if ( ASyncMode() )
  1099. {
  1100. int n_rects_words = count * N_DWORDS( D3DRECT );
  1101. AllocatePushBufferSpace( 2 + n_rects_words + 4 );
  1102. *(m_pOutputPtr++) = PBCMD_CLEAR;
  1103. *(m_pOutputPtr++) = count;
  1104. if ( count )
  1105. {
  1106. memcpy( m_pOutputPtr, pRects, count * sizeof( D3DRECT ) );
  1107. m_pOutputPtr += n_rects_words;
  1108. }
  1109. *(m_pOutputPtr++) = Flags;
  1110. *( (D3DCOLOR *) m_pOutputPtr ) = color;
  1111. m_pOutputPtr++;
  1112. *( (float *) m_pOutputPtr ) = Z;
  1113. m_pOutputPtr++;
  1114. *(m_pOutputPtr++) = stencil;
  1115. }
  1116. else
  1117. DO_D3D( Clear(count, pRects, Flags, color, Z, stencil) );
  1118. }
  1119. HRESULT Reset( D3DPRESENT_PARAMETERS *parms)
  1120. {
  1121. RECORD_COMMAND( DX8_RESET, 1 );
  1122. RECORD_STRUCT( parms, sizeof(*parms) );
  1123. Synchronize();
  1124. return m_pD3DDevice->Reset( parms );
  1125. }
  1126. void Release( void )
  1127. {
  1128. Synchronize();
  1129. DO_D3D( Release() );
  1130. }
  1131. FORCEINLINE void SetTexture(int stage, IDirect3DBaseTexture9 *txtr)
  1132. {
  1133. RECORD_COMMAND( DX8_SET_TEXTURE, 3 );
  1134. RECORD_INT( stage );
  1135. RECORD_INT( -1 );
  1136. RECORD_INT( -1 );
  1137. if (ASyncMode())
  1138. {
  1139. Push( PBCMD_SET_TEXTURE, stage, txtr );
  1140. }
  1141. else
  1142. DO_D3D( SetTexture( stage, txtr) );
  1143. }
  1144. void SetTransform( D3DTRANSFORMSTATETYPE mtrx_id, D3DXMATRIX const *mt)
  1145. {
  1146. RECORD_COMMAND( DX8_SET_TRANSFORM, 2 );
  1147. RECORD_INT( mtrx_id );
  1148. RECORD_STRUCT( mt, sizeof(D3DXMATRIX) );
  1149. Synchronize();
  1150. DO_D3D( SetTransform( mtrx_id, mt) );
  1151. }
  1152. FORCEINLINE void SetSamplerState( int stage, D3DSAMPLERSTATETYPE state, DWORD val)
  1153. {
  1154. RECORD_SAMPLER_STATE( stage, state, val );
  1155. if ( ASyncMode() )
  1156. Push( PBCMD_SET_SAMPLER_STATE, stage, state, val );
  1157. else
  1158. DO_D3D( SetSamplerState( stage, state, val) );
  1159. }
  1160. #ifdef DX_TO_GL_ABSTRACTION
  1161. FORCEINLINE void SetSamplerStates( DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, DWORD MinFilter, DWORD MagFilter, DWORD MipFilter )
  1162. {
  1163. RECORD_SAMPLER_STATES( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter );
  1164. if (ASyncMode())
  1165. Push( PBCMD_SET_SAMPLER_STATES, Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter );
  1166. else
  1167. DO_D3D( SetSamplerStates( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter ) );
  1168. }
  1169. #endif
  1170. void SetFVF( int fvf)
  1171. {
  1172. Synchronize();
  1173. DO_D3D( SetFVF( fvf) );
  1174. }
  1175. FORCEINLINE void SetTextureStageState( int stage, D3DTEXTURESTAGESTATETYPE state, DWORD val )
  1176. {
  1177. RECORD_TEXTURE_STAGE_STATE( stage, state, val );
  1178. Synchronize();
  1179. DO_D3D( SetTextureStageState( stage, state, val) );
  1180. }
  1181. FORCEINLINE void DrawPrimitive(
  1182. D3DPRIMITIVETYPE PrimitiveType,
  1183. UINT StartVertex,
  1184. UINT PrimitiveCount
  1185. )
  1186. {
  1187. RECORD_COMMAND( DX8_DRAW_PRIMITIVE, 3 );
  1188. RECORD_INT( PrimitiveType );
  1189. RECORD_INT( StartVertex );
  1190. RECORD_INT( PrimitiveCount );
  1191. if ( ASyncMode() )
  1192. {
  1193. Push( PBCMD_DRAWPRIM, PrimitiveType, StartVertex, PrimitiveCount );
  1194. SubmitIfNotBusy();
  1195. }
  1196. else
  1197. DO_D3D( DrawPrimitive( PrimitiveType, StartVertex, PrimitiveCount ) );
  1198. }
  1199. HRESULT CreateVertexDeclaration(
  1200. CONST D3DVERTEXELEMENT9* pVertexElements,
  1201. IDirect3DVertexDeclaration9** ppDecl
  1202. )
  1203. {
  1204. Synchronize();
  1205. return m_pD3DDevice->CreateVertexDeclaration( pVertexElements, ppDecl );
  1206. }
  1207. HRESULT ValidateDevice( DWORD * pNumPasses )
  1208. {
  1209. Synchronize();
  1210. return m_pD3DDevice->ValidateDevice( pNumPasses );
  1211. }
  1212. HRESULT CreateVertexShader(
  1213. CONST DWORD * pFunction,
  1214. IDirect3DVertexShader9** ppShader,
  1215. const char *pShaderName,
  1216. char *debugLabel = NULL
  1217. )
  1218. {
  1219. Synchronize();
  1220. #ifdef DX_TO_GL_ABSTRACTION
  1221. return m_pD3DDevice->CreateVertexShader( pFunction, ppShader, pShaderName, debugLabel );
  1222. #else
  1223. return m_pD3DDevice->CreateVertexShader( pFunction, ppShader );
  1224. #endif
  1225. }
  1226. HRESULT CreatePixelShader(
  1227. CONST DWORD * pFunction,
  1228. IDirect3DPixelShader9** ppShader,
  1229. const char *pShaderName,
  1230. char *debugLabel = NULL,
  1231. const uint32 *pCentroidMask = NULL
  1232. )
  1233. {
  1234. Synchronize();
  1235. #ifdef DX_TO_GL_ABSTRACTION
  1236. return m_pD3DDevice->CreatePixelShader( pFunction, ppShader, pShaderName, debugLabel, pCentroidMask );
  1237. #else
  1238. return m_pD3DDevice->CreatePixelShader( pFunction, ppShader );
  1239. #endif
  1240. }
  1241. FORCEINLINE void SetIndices(
  1242. IDirect3DIndexBuffer9 * pIndexData
  1243. )
  1244. {
  1245. if ( ASyncMode() )
  1246. Push( PBCMD_SET_INDICES, pIndexData );
  1247. else
  1248. DO_D3D( SetIndices( pIndexData ) );
  1249. }
  1250. FORCEINLINE void SetStreamSource(
  1251. UINT StreamNumber,
  1252. IDirect3DVertexBuffer9 * pStreamData,
  1253. UINT OffsetInBytes,
  1254. UINT Stride
  1255. )
  1256. {
  1257. if ( ASyncMode() )
  1258. Push( PBCMD_SET_STREAM_SOURCE, StreamNumber, pStreamData, OffsetInBytes, Stride );
  1259. else
  1260. DO_D3D( SetStreamSource( StreamNumber, pStreamData, OffsetInBytes, Stride ) );
  1261. }
  1262. HRESULT CreateVertexBuffer(
  1263. UINT Length,
  1264. DWORD Usage,
  1265. DWORD FVF,
  1266. D3DPOOL Pool,
  1267. IDirect3DVertexBuffer9** ppVertexBuffer,
  1268. HANDLE* pSharedHandle
  1269. )
  1270. {
  1271. Synchronize();
  1272. return m_pD3DDevice->CreateVertexBuffer( Length, Usage, FVF,
  1273. Pool, ppVertexBuffer, pSharedHandle );
  1274. }
  1275. HRESULT CreateIndexBuffer(
  1276. UINT Length,
  1277. DWORD Usage,
  1278. D3DFORMAT Format,
  1279. D3DPOOL Pool,
  1280. IDirect3DIndexBuffer9** ppIndexBuffer,
  1281. HANDLE* pSharedHandle
  1282. )
  1283. {
  1284. Synchronize();
  1285. return m_pD3DDevice->CreateIndexBuffer( Length, Usage, Format, Pool, ppIndexBuffer,
  1286. pSharedHandle );
  1287. }
  1288. FORCEINLINE void DrawIndexedPrimitive(
  1289. D3DPRIMITIVETYPE Type,
  1290. INT BaseVertexIndex,
  1291. UINT MinIndex,
  1292. UINT NumVertices,
  1293. UINT StartIndex,
  1294. UINT PrimitiveCount )
  1295. {
  1296. RECORD_COMMAND( DX8_DRAW_INDEXED_PRIMITIVE, 6 );
  1297. RECORD_INT( Type );
  1298. RECORD_INT( BaseVertexIndex );
  1299. RECORD_INT( MinIndex );
  1300. RECORD_INT( NumVertices );
  1301. RECORD_INT( StartIndex );
  1302. RECORD_INT( PrimitiveCount );
  1303. if ( ASyncMode() )
  1304. {
  1305. Push(PBCMD_DRAWINDEXEDPRIM,
  1306. Type, BaseVertexIndex, MinIndex, NumVertices, StartIndex, PrimitiveCount );
  1307. // SubmitIfNotBusy();
  1308. }
  1309. else
  1310. {
  1311. DO_D3D( DrawIndexedPrimitive( Type, BaseVertexIndex, MinIndex, NumVertices, StartIndex, PrimitiveCount ) );
  1312. }
  1313. }
  1314. #ifndef DX_TO_GL_ABSTRACTION
  1315. FORCEINLINE void DrawPrimitiveUP_RESZ( const void *pVertexStream )
  1316. {
  1317. if ( ASyncMode() )
  1318. {
  1319. Push( PBCMD_DRAWPRIMUP_RESZ );
  1320. // SubmitIfNotBusy();
  1321. }
  1322. else
  1323. {
  1324. DO_D3D( DrawPrimitiveUP( D3DPT_POINTLIST, 1, pVertexStream, 3 * sizeof( float ) ) );
  1325. }
  1326. }
  1327. FORCEINLINE void DrawTessellatedIndexedPrimitive( INT BaseVertexIndex, UINT MinIndex, UINT NumVertices,
  1328. UINT StartIndex, UINT PrimitiveCount )
  1329. {
  1330. // Setup our stream-source frequencies
  1331. DO_D3D( SetStreamSourceFreq( 0, D3DSTREAMSOURCE_INDEXEDDATA | PrimitiveCount ) );
  1332. DO_D3D( SetStreamSourceFreq( VertexStreamSpec_t::STREAM_MORPH, D3DSTREAMSOURCE_INSTANCEDATA | 1ul ) );
  1333. DO_D3D( SetStreamSourceFreq( VertexStreamSpec_t::STREAM_SUBDQUADS, D3DSTREAMSOURCE_INSTANCEDATA | 1ul ) );
  1334. int nIndicesPerPatch = ( ( ( m_nCurrentTessLevel + 1 ) * 2 + 2 ) * m_nCurrentTessLevel ) - 2;
  1335. int nVerticesPerPatch = m_nCurrentTessLevel + 1;
  1336. nVerticesPerPatch *= nVerticesPerPatch;
  1337. int nPrimitiveCount = nIndicesPerPatch - 2;
  1338. DO_D3D( DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, nVerticesPerPatch, 0, nPrimitiveCount ) );
  1339. // Disable instancing
  1340. DO_D3D( SetStreamSourceFreq( 0, 1ul ) );
  1341. DO_D3D( SetStreamSourceFreq( VertexStreamSpec_t::STREAM_MORPH, 1ul ) );
  1342. DO_D3D( SetStreamSourceFreq( VertexStreamSpec_t::STREAM_SUBDQUADS, 1ul ) );
  1343. }
  1344. FORCEINLINE void DrawTessellatedPrimitive( UINT StartVertex, UINT PrimitiveCount )
  1345. {
  1346. // Setup our stream-source frequencies
  1347. DO_D3D( SetStreamSourceFreq( 0, D3DSTREAMSOURCE_INDEXEDDATA | PrimitiveCount ) );
  1348. DO_D3D( SetStreamSourceFreq( VertexStreamSpec_t::STREAM_MORPH, D3DSTREAMSOURCE_INSTANCEDATA | 1ul ) );
  1349. DO_D3D( SetStreamSourceFreq( VertexStreamSpec_t::STREAM_SUBDQUADS, D3DSTREAMSOURCE_INSTANCEDATA | 1ul ) );
  1350. int nIndicesPerPatch = ( ( ( m_nCurrentTessLevel + 1 ) * 2 + 2 ) * m_nCurrentTessLevel ) - 2;
  1351. int nVerticesPerPatch = m_nCurrentTessLevel + 1;
  1352. nVerticesPerPatch *= nVerticesPerPatch;
  1353. int nPrimitiveCount = nIndicesPerPatch - 2;
  1354. DO_D3D( DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, nVerticesPerPatch, 0, nPrimitiveCount ) );
  1355. // Disable instancing
  1356. DO_D3D( SetStreamSourceFreq( 0, 1ul ) );
  1357. DO_D3D( SetStreamSourceFreq( VertexStreamSpec_t::STREAM_MORPH, 1ul ) );
  1358. DO_D3D( SetStreamSourceFreq( VertexStreamSpec_t::STREAM_SUBDQUADS, 1ul ) );
  1359. }
  1360. FORCEINLINE void SetTessellationLevel( float level )
  1361. {
  1362. // Track our current tessellation level
  1363. m_nCurrentTessLevel = (int)ceil( level );
  1364. }
  1365. #endif
  1366. void SetMaterial( D3DMATERIAL9 const *mat)
  1367. {
  1368. RECORD_COMMAND( DX8_SET_MATERIAL, 1 );
  1369. RECORD_STRUCT( &mat, sizeof(mat) );
  1370. Synchronize();
  1371. DO_D3D( SetMaterial( mat ) );
  1372. }
  1373. FORCEINLINE void SetPixelShader( IDirect3DPixelShader9 *pShader )
  1374. {
  1375. RECORD_COMMAND( DX8_SET_PIXEL_SHADER, 1 );
  1376. RECORD_INT( ( int ) pShader );
  1377. if ( ASyncMode() )
  1378. Push( PBCMD_SET_PIXEL_SHADER, pShader );
  1379. else
  1380. DO_D3D( SetPixelShader( pShader ) );
  1381. }
  1382. FORCEINLINE void SetVertexShader( IDirect3DVertexShader9 *pShader )
  1383. {
  1384. if ( ASyncMode() )
  1385. Push( PBCMD_SET_VERTEX_SHADER, pShader );
  1386. else
  1387. DO_D3D( SetVertexShader( pShader ) );
  1388. }
  1389. #ifdef DX_TO_GL_ABSTRACTION
  1390. FORCEINLINE HRESULT LinkShaderPair( IDirect3DVertexShader9* vs, IDirect3DPixelShader9* ps )
  1391. {
  1392. Assert ( !ASyncMode() );
  1393. return DO_D3D( LinkShaderPair( vs, ps ) );
  1394. }
  1395. FORCEINLINE HRESULT ValidateShaderPair( IDirect3DVertexShader9* vs, IDirect3DPixelShader9* ps )
  1396. {
  1397. Assert( !ASyncMode() );
  1398. return DO_D3D( ValidateShaderPair( vs, ps ) );
  1399. }
  1400. HRESULT QueryShaderPair( int index, GLMShaderPairInfo *infoOut )
  1401. {
  1402. Assert ( !ASyncMode() );
  1403. return DO_D3D( QueryShaderPair( index, infoOut ) );
  1404. }
  1405. #endif
  1406. void EvictManagedResources( void )
  1407. {
  1408. if (m_pD3DDevice) // people call this before creating the device
  1409. {
  1410. Synchronize();
  1411. DO_D3D( EvictManagedResources() );
  1412. }
  1413. }
  1414. void SetLight( int i, D3DLIGHT9 const *l)
  1415. {
  1416. RECORD_COMMAND( DX8_SET_LIGHT, 2 );
  1417. RECORD_INT( i );
  1418. RECORD_STRUCT( l, sizeof(*l) );
  1419. Synchronize();
  1420. DO_D3D( SetLight(i, l) );
  1421. }
  1422. void DrawIndexedPrimitiveUP( D3DPRIMITIVETYPE PrimitiveType,
  1423. UINT MinVertexIndex,
  1424. UINT NumVertices,
  1425. UINT PrimitiveCount,
  1426. CONST void * pIndexData,
  1427. D3DFORMAT IndexDataFormat,
  1428. CONST void* pVertexStreamZeroData,
  1429. UINT VertexStreamZeroStride )
  1430. {
  1431. Synchronize();
  1432. DO_D3D( DrawIndexedPrimitiveUP( PrimitiveType, MinVertexIndex, NumVertices, PrimitiveCount,
  1433. pIndexData, IndexDataFormat, pVertexStreamZeroData,
  1434. VertexStreamZeroStride ) );
  1435. }
  1436. HRESULT Present(
  1437. CONST RECT * pSourceRect,
  1438. CONST RECT * pDestRect,
  1439. VD3DHWND hDestWindowOverride,
  1440. CONST RGNDATA * pDirtyRegion)
  1441. {
  1442. RECORD_COMMAND( DX8_PRESENT, 0 );
  1443. if ( ASyncMode() )
  1444. {
  1445. // need to deal with ret code here
  1446. AllocatePushBufferSpace(1+1+
  1447. N_DWORDS( RECT )+1+N_DWORDS( RECT )+1+1+N_DWORDS( RGNDATA ));
  1448. *(m_pOutputPtr++)=PBCMD_PRESENT;
  1449. *(m_pOutputPtr++)=( pSourceRect != NULL );
  1450. if (pSourceRect)
  1451. memcpy(m_pOutputPtr, pSourceRect, sizeof( RECT ) );
  1452. m_pOutputPtr+=N_DWORDS( RECT );
  1453. *(m_pOutputPtr++)=( pDestRect != NULL );
  1454. if (pDestRect)
  1455. memcpy(m_pOutputPtr, pDestRect, sizeof( RECT ) );
  1456. m_pOutputPtr+=N_DWORDS( RECT );
  1457. *(m_pOutputPtr++)=size_cast< uint32 >( (uintp) hDestWindowOverride );
  1458. *(m_pOutputPtr++)=( pDirtyRegion != NULL );
  1459. if (pDirtyRegion)
  1460. memcpy(m_pOutputPtr, pDirtyRegion, sizeof( RGNDATA ));
  1461. m_pOutputPtr+=N_DWORDS( RGNDATA );
  1462. return S_OK; // not good - caller wants to here about lost devices
  1463. }
  1464. else
  1465. return m_pD3DDevice->Present( pSourceRect, pDestRect,
  1466. hDestWindowOverride, pDirtyRegion );
  1467. }
  1468. #ifdef _PS3
  1469. void GetGPUMemoryStats( GPUMemoryStats &stats )
  1470. {
  1471. m_pD3DDevice->GetGPUMemoryStats( stats );
  1472. }
  1473. void BeginZPass( DWORD Flags )
  1474. {
  1475. m_pD3DDevice->BeginZPass();
  1476. }
  1477. void SetPredication( DWORD PredicationMask )
  1478. {
  1479. m_pD3DDevice->SetPredication( PredicationMask );
  1480. }
  1481. HRESULT EndZPass()
  1482. {
  1483. return m_pD3DDevice->EndZPass();
  1484. }
  1485. #endif // _PS3
  1486. #ifdef DX_TO_GL_ABSTRACTION
  1487. FORCEINLINE void AcquireThreadOwnership( void )
  1488. {
  1489. if (ASyncMode())
  1490. Push( PBCMD_ACQUIRE_THREAD_OWNERSHIP );
  1491. else
  1492. DO_D3D( AcquireThreadOwnership() );
  1493. }
  1494. FORCEINLINE void ReleaseThreadOwnership( void )
  1495. {
  1496. if (ASyncMode())
  1497. Push( PBCMD_RELEASE_THREAD_OWNERSHIP );
  1498. else
  1499. DO_D3D( ReleaseThreadOwnership() );
  1500. }
  1501. #endif
  1502. };
  1503. #endif // D3DASYNC_H