Source code of Windows XP (NT5)
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.

304 lines
9.2 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 2000.
  3. //
  4. // debugmon.cpp
  5. //
  6. // Direct3D Debug Monitor
  7. //
  8. //
  9. // MUST BE KEPT IN SYNC WITH debugmon.cpp IN REF8\RAST
  10. //
  11. ///////////////////////////////////////////////////////////////////////////////
  12. /*
  13. WORKLIST
  14. - vertex shader source <-> debugger
  15. */
  16. #include "pch.cpp"
  17. #pragma hdrstop
  18. #include <process.h>
  19. #include "debugmon.hpp"
  20. //-----------------------------------------------------------------------------
  21. //
  22. //-----------------------------------------------------------------------------
  23. D3DDebugMonitor::D3DDebugMonitor( void )
  24. {
  25. // get pid and create DebugTargetContext sharedmem
  26. int pid = _getpid();
  27. m_pTgtCtxSM = new D3DSharedMem( sizeof(DebugTargetContext), D3DDM_TGTCTX_SM "%d", pid );
  28. m_pTgtCtx = (DebugTargetContext*)(m_pTgtCtxSM->GetPtr());
  29. memset( m_pTgtCtx, 0x0, sizeof(DebugTargetContext) );
  30. m_pTgtCtx->Version = D3DDM_VERSION;
  31. m_pTgtCtx->ProcessID = pid;
  32. // create target events
  33. char name[128];
  34. _snprintf( name, 128, D3DDM_TGT_EVENTBP "%d", m_pTgtCtx->ProcessID );
  35. m_hTgtEventBP = CreateEvent( NULL, FALSE, FALSE, name );
  36. DDASSERT( m_hTgtEventBP );
  37. _snprintf( name, 128, D3DDM_TGT_EVENTACK "%d", m_pTgtCtx->ProcessID );
  38. m_hTgtEventAck = CreateEvent( NULL, FALSE, FALSE, name );
  39. DDASSERT( m_hTgtEventAck );
  40. // null out monitor connections
  41. m_pMonCtx = NULL;
  42. m_pMonCtxSM = NULL;
  43. m_pCmdData = NULL;
  44. m_pCmdDataSM = NULL;
  45. m_hMonEventCmd = 0;
  46. }
  47. //-----------------------------------------------------------------------------
  48. D3DDebugMonitor::~D3DDebugMonitor( void )
  49. {
  50. // send disconnect event to monitor
  51. m_pTgtCtx->EventStatus = D3DDM_EVENT_TARGETEXIT;
  52. SetEvent( m_hTgtEventBP );
  53. DetachMonitorConnection();
  54. CloseHandle( m_hTgtEventBP );
  55. CloseHandle( m_hTgtEventAck );
  56. delete m_pTgtCtxSM;
  57. }
  58. //-----------------------------------------------------------------------------
  59. //
  60. //-----------------------------------------------------------------------------
  61. HRESULT
  62. D3DDebugMonitor::AttachToMonitor( int iMon )
  63. {
  64. #if(D3D_DEBUGMON>0x00)
  65. if (iMon < 1) return E_FAIL;
  66. if (MonitorConnected() || !m_bDbgMonConnectionEnabled)
  67. {
  68. return E_FAIL;
  69. }
  70. // attach to monitor context
  71. m_pMonCtxSM = new D3DSharedMem( sizeof(DebugMonitorContext), D3DDM_MONCTX_SM "%d", iMon );
  72. if ( !m_pMonCtxSM->AlreadyExisted() ) goto _fail_return; // monitor not there
  73. // get pointer to monitor context bits
  74. m_pMonCtx = (const DebugMonitorContext*)m_pMonCtxSM->GetPtr();
  75. if (m_pMonCtx->TargetID) goto _fail_return; // monitor already taken
  76. // request attachment to this context (cast to non-const just this once...)
  77. ((DebugMonitorContext*)m_pMonCtx)->TargetIDRequest = m_pTgtCtx->ProcessID;
  78. // attach to monitor event acknowledge
  79. char name[128];
  80. _snprintf( name, 128, D3DDM_MON_EVENTCMD "%d", iMon );
  81. m_hMonEventCmd = OpenEvent( EVENT_ALL_ACCESS, NULL, name );
  82. // signal monitor via it's own event (just this once) and wait for reply on our ack
  83. D3D_INFO(0, "D3DDebugTarget - attempting to attach to monitor");
  84. SignalObjectAndWait( m_hMonEventCmd, m_hTgtEventAck, INFINITE, FALSE );
  85. if ( m_pMonCtx->TargetID != m_pTgtCtx->ProcessID ) goto _fail_return;
  86. // monitor is attached to this target
  87. m_pTgtCtx->MonitorID = iMon;
  88. // attach to command data SM
  89. m_pCmdDataSM = new D3DSharedMem( D3DDM_CMDDATA_SIZE,
  90. D3DDM_CMDDATA_SM "%d", m_pTgtCtx->MonitorID );
  91. m_pCmdData = (DebugMonitorContext*)(m_pCmdDataSM->GetPtr());
  92. // tell monitor that we are done attaching
  93. SetEvent( m_hTgtEventBP );
  94. D3D_INFO(0, "D3DDebugTarget - debug monitor attached");
  95. return S_OK;
  96. _fail_return:
  97. if (m_pMonCtxSM) delete m_pMonCtxSM;
  98. m_pMonCtxSM = NULL;
  99. m_pMonCtx = NULL;
  100. if (m_hMonEventCmd) CloseHandle( m_hMonEventCmd ); m_hMonEventCmd = 0;
  101. return E_FAIL;
  102. #else
  103. return E_FAIL;
  104. #endif
  105. }
  106. //-----------------------------------------------------------------------------
  107. // drop connection
  108. //-----------------------------------------------------------------------------
  109. void
  110. D3DDebugMonitor::DetachMonitorConnection( void )
  111. {
  112. #if(D3D_DEBUGMON>0x00)
  113. #ifdef DBG
  114. // SD build complains in free build about empty statement in this if
  115. // so only do this in debug (MonitorConnected has no evil side effects)
  116. if (MonitorConnected())
  117. D3D_INFO(0, "D3DDebugTarget - debug monitor detached");
  118. #endif // DBG
  119. // drop attachment to monitor and delete monitor context attachment
  120. m_pTgtCtx->MonitorID = 0; // let monitor know it is being dropped
  121. if (NULL != m_pMonCtxSM) delete m_pMonCtxSM; m_pMonCtxSM = NULL;
  122. m_pMonCtx = NULL;
  123. if (NULL != m_pCmdDataSM) delete m_pCmdDataSM; m_pCmdDataSM = NULL;
  124. m_pCmdData = NULL;
  125. ResetEvent( m_hMonEventCmd );
  126. if (m_hMonEventCmd) CloseHandle( m_hMonEventCmd ); m_hMonEventCmd = NULL;
  127. #endif
  128. }
  129. //-----------------------------------------------------------------------------
  130. // check for lost monitor connection, and clean up if necessary
  131. //-----------------------------------------------------------------------------
  132. BOOL
  133. D3DDebugMonitor::CheckLostMonitorConnection( void )
  134. {
  135. #if(D3D_DEBUGMON>0x00)
  136. if ( !m_pMonCtx )
  137. {
  138. // not connected
  139. return TRUE;
  140. }
  141. if ( m_pMonCtx->TargetID != m_pTgtCtx->ProcessID )
  142. {
  143. // we have been disconnected
  144. DetachMonitorConnection();
  145. return TRUE;
  146. }
  147. return FALSE;
  148. #else
  149. return TRUE;
  150. #endif
  151. }
  152. //-----------------------------------------------------------------------------
  153. //
  154. //-----------------------------------------------------------------------------
  155. BOOL
  156. D3DDebugMonitor::IsEventBreak( UINT32 EventType )
  157. {
  158. BOOL bReturn = FALSE;
  159. #define _D3DDM_EVENT_CASE( _Event) \
  160. case D3DDM_EVENT_##_Event: if (MonitorEventBP() & D3DDM_EVENT_##_Event) { bReturn = TRUE; } break
  161. // keep this as single line per event - convenient place to set debugger breakpoints
  162. switch ( EventType )
  163. {
  164. _D3DDM_EVENT_CASE(RSTOKEN);
  165. _D3DDM_EVENT_CASE(BEGINSCENE);
  166. _D3DDM_EVENT_CASE(ENDSCENE);
  167. _D3DDM_EVENT_CASE(VERTEX);
  168. _D3DDM_EVENT_CASE(VERTEXSHADERINST);
  169. _D3DDM_EVENT_CASE(PRIMITIVE);
  170. _D3DDM_EVENT_CASE(PIXEL);
  171. _D3DDM_EVENT_CASE(PIXELSHADERINST);
  172. default: break;
  173. }
  174. return bReturn;
  175. }
  176. //-----------------------------------------------------------------------------
  177. //
  178. //-----------------------------------------------------------------------------
  179. HRESULT
  180. D3DDebugMonitor::MonitorBreakpoint( void )
  181. {
  182. CheckLostMonitorConnection();
  183. if ( !MonitorConnected() ) return S_OK;
  184. // tell monitor that we are at an event breakpoint
  185. SetEvent( m_hTgtEventBP );
  186. D3D_INFO(0, "D3DDebugTarget - stopped in debug monitor");
  187. // spin here responding to commands until command given to go
  188. BOOL bResume = FALSE;
  189. while ( !bResume )
  190. {
  191. // wait for command to be issued (or monitor dropped)
  192. WaitForSingleObject( m_hMonEventCmd, INFINITE );
  193. if ( CheckLostMonitorConnection() )
  194. {
  195. bResume = TRUE;
  196. break;
  197. }
  198. // process command
  199. switch ( m_pMonCtx->Command & D3DDM_CMD_MASK )
  200. {
  201. case D3DDM_CMD_GO:
  202. m_pTgtCtx->CommandBufferSize = 0;
  203. bResume = TRUE;
  204. break;
  205. default:
  206. ProcessMonitorCommand();
  207. break;
  208. }
  209. // acknowledge command processing done
  210. SetEvent( m_hTgtEventAck );
  211. }
  212. D3D_INFO(0, "D3DDebugTarget - resumed");
  213. return S_OK;
  214. }
  215. //-----------------------------------------------------------------------------
  216. //
  217. // Generic shared memory object, implemented using Win32 file mapping.
  218. // _snprintf interface for name.
  219. //
  220. // 6/20/2000(RichGr) - IA64: Change first parameter from int to INT_PTR so that
  221. // all parameters are the same length. This is needed to make the va_start
  222. // macro work correctly.
  223. //
  224. //-----------------------------------------------------------------------------
  225. D3DSharedMem::D3DSharedMem( INT_PTR cbSize, const char* pszFormat, ... )
  226. {
  227. m_pMem = NULL;
  228. char pszName[1024] = "\0";
  229. va_list marker;
  230. va_start(marker, pszFormat);
  231. _vsnprintf(pszName+lstrlen(pszName), 1024-lstrlen(pszName), pszFormat, marker);
  232. // 6/20/2000(RichGr) - IA64: Change file handle from (HANDLE)0xFFFFFFF to INVALID_HANDLE_VALUE.
  233. // This generates the correct -1 value for both 32-bit and 64-bit builds.
  234. m_hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,
  235. NULL, PAGE_READWRITE, 0, (DWORD)cbSize, pszName);
  236. // check if it existed already
  237. m_bAlreadyExisted = (m_hFileMap != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS);
  238. if (NULL == m_hFileMap)
  239. {
  240. DDASSERT(0);
  241. }
  242. else
  243. {
  244. // Map a view of the file into the address space.
  245. m_pMem = (void *)MapViewOfFile(m_hFileMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
  246. if (NULL == m_pMem)
  247. {
  248. DDASSERT(0);
  249. if (NULL != m_hFileMap) CloseHandle(m_hFileMap);
  250. }
  251. }
  252. }
  253. D3DSharedMem::~D3DSharedMem(void)
  254. {
  255. if (NULL != m_pMem) UnmapViewOfFile((LPVOID) m_pMem);
  256. if (NULL != m_hFileMap) CloseHandle(m_hFileMap);
  257. }
  258. ///////////////////////////////////////////////////////////////////////////////
  259. // end