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.

263 lines
7.7 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 2000.
  3. //
  4. // debugmon.cpp
  5. //
  6. // Direct3D Debug Monitor
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. /*
  10. WORKLIST
  11. - vertex shader source <-> debugger
  12. */
  13. #include "pch.cpp"
  14. #pragma hdrstop
  15. #include <process.h>
  16. #include "d3ddm.hpp"
  17. //-----------------------------------------------------------------------------
  18. //
  19. //-----------------------------------------------------------------------------
  20. D3DDebugMonitor::D3DDebugMonitor( void )
  21. {
  22. // get pid and create DebugTargetContext sharedmem
  23. int pid = _getpid();
  24. m_pTgtCtxSM = new D3DSharedMem( sizeof(DebugTargetContext), D3DDM_TGTCTX_SM "%d", pid );
  25. if( m_pTgtCtxSM == NULL )
  26. {
  27. DPFERR( "new D3DSharedMem failed" );
  28. m_pTgtCtx = NULL;
  29. m_pTgtCtxSM = NULL;
  30. m_hTgtEventBP = NULL;
  31. m_hTgtEventAck = NULL;
  32. goto Error_Return;
  33. }
  34. m_pTgtCtx = (DebugTargetContext*)(m_pTgtCtxSM->GetPtr());
  35. memset( m_pTgtCtx, 0x0, sizeof(DebugTargetContext) );
  36. m_pTgtCtx->ProcessID = pid;
  37. m_pTgtCtx->Version = D3DDM_VERSION;
  38. // create target events
  39. char name[128];
  40. _snprintf( name, 128, D3DDM_TGT_EVENTBP "%d", m_pTgtCtx->ProcessID );
  41. m_hTgtEventBP = CreateEvent( NULL, FALSE, FALSE, name );
  42. _ASSERT( m_hTgtEventBP ,"CreateEvent for target event BP failed")
  43. _snprintf( name, 128, D3DDM_TGT_EVENTACK "%d", m_pTgtCtx->ProcessID );
  44. m_hTgtEventAck = CreateEvent( NULL, FALSE, FALSE, name );
  45. _ASSERT( m_hTgtEventAck ,"CreateEvent for target event ACK failed");
  46. Error_Return:
  47. // null out monitor connections
  48. m_pMonCtx = NULL;
  49. m_pMonCtxSM = NULL;
  50. m_pCmdData = NULL;
  51. m_pCmdDataSM = NULL;
  52. m_hMonEventCmd = 0;
  53. return;
  54. }
  55. //-----------------------------------------------------------------------------
  56. D3DDebugMonitor::~D3DDebugMonitor( void )
  57. {
  58. // send disconnect event to monitor
  59. m_pTgtCtx->EventStatus = D3DDM_EVENT_TARGETEXIT;
  60. SetEvent( m_hTgtEventBP );
  61. DetachMonitorConnection();
  62. CloseHandle( m_hTgtEventBP );
  63. CloseHandle( m_hTgtEventAck );
  64. delete m_pTgtCtxSM;
  65. }
  66. //-----------------------------------------------------------------------------
  67. //
  68. //-----------------------------------------------------------------------------
  69. HRESULT
  70. D3DDebugMonitor::AttachToMonitor( int iMon )
  71. {
  72. #if(D3D_DEBUGMON>0x00)
  73. if (iMon < 1) return E_FAIL;
  74. if (MonitorConnected() || !m_bDbgMonConnectionEnabled)
  75. {
  76. return E_FAIL;
  77. }
  78. // attach to monitor context
  79. m_pMonCtxSM = new D3DSharedMem( sizeof(DebugMonitorContext), D3DDM_MONCTX_SM "%d", iMon );
  80. if ( (m_pMonCtxSM == NULL) || !m_pMonCtxSM->AlreadyExisted() ) goto _fail_return; // monitor not there
  81. // get pointer to monitor context bits
  82. m_pMonCtx = (const DebugMonitorContext*)m_pMonCtxSM->GetPtr();
  83. if (m_pMonCtx->TargetID) goto _fail_return; // monitor already taken
  84. // request attachment to this context (cast to non-const just this once...)
  85. ((DebugMonitorContext*)m_pMonCtx)->TargetIDRequest = m_pTgtCtx->ProcessID;
  86. // attach to monitor event acknowledge
  87. char name[128];
  88. _snprintf( name, 128, D3DDM_MON_EVENTCMD "%d", iMon );
  89. m_hMonEventCmd = OpenEvent( EVENT_ALL_ACCESS, NULL, name );
  90. // signal monitor via it's own event (just this once) and wait for reply on our ack
  91. DPFINFO("D3DDebugTarget - attempting to attach to monitor");
  92. SignalObjectAndWait( m_hMonEventCmd, m_hTgtEventAck, INFINITE, FALSE );
  93. if ( m_pMonCtx->TargetID != m_pTgtCtx->ProcessID ) goto _fail_return;
  94. // monitor is attached to this target
  95. m_pTgtCtx->MonitorID = iMon;
  96. // attach to command data SM
  97. m_pCmdDataSM = new D3DSharedMem( D3DDM_CMDDATA_SIZE,
  98. D3DDM_CMDDATA_SM "%d", m_pTgtCtx->MonitorID );
  99. m_pCmdData = (DebugMonitorContext*)(m_pCmdDataSM->GetPtr());
  100. // tell monitor that we are done attaching
  101. SetEvent( m_hTgtEventBP );
  102. DPFINFO("D3DDebugTarget - debug monitor attached");
  103. return S_OK;
  104. _fail_return:
  105. if (m_pMonCtxSM) delete m_pMonCtxSM;
  106. m_pMonCtxSM = NULL;
  107. m_pMonCtx = NULL;
  108. if (m_hMonEventCmd) CloseHandle( m_hMonEventCmd ); m_hMonEventCmd = 0;
  109. return E_FAIL;
  110. #else
  111. return E_FAIL;
  112. #endif
  113. }
  114. //-----------------------------------------------------------------------------
  115. // drop connection
  116. //-----------------------------------------------------------------------------
  117. void
  118. D3DDebugMonitor::DetachMonitorConnection( void )
  119. {
  120. #if(D3D_DEBUGMON>0x00)
  121. if (MonitorConnected())
  122. DPFINFO("D3DDebugTarget - debug monitor detached");
  123. // drop attachment to monitor and delete monitor context attachment
  124. m_pTgtCtx->MonitorID = 0; // let monitor know it is being dropped
  125. if (NULL != m_pMonCtxSM) delete m_pMonCtxSM; m_pMonCtxSM = NULL;
  126. m_pMonCtx = NULL;
  127. if (NULL != m_pCmdDataSM) delete m_pCmdDataSM; m_pCmdDataSM = NULL;
  128. m_pCmdData = NULL;
  129. ResetEvent( m_hMonEventCmd );
  130. if (m_hMonEventCmd) CloseHandle( m_hMonEventCmd ); m_hMonEventCmd = NULL;
  131. #endif
  132. }
  133. //-----------------------------------------------------------------------------
  134. // check for lost monitor connection, and clean up if necessary
  135. //-----------------------------------------------------------------------------
  136. BOOL
  137. D3DDebugMonitor::CheckLostMonitorConnection( void )
  138. {
  139. #if(D3D_DEBUGMON>0x00)
  140. if ( !m_pMonCtx )
  141. {
  142. // not connected
  143. return TRUE;
  144. }
  145. if ( m_pMonCtx->TargetID != m_pTgtCtx->ProcessID )
  146. {
  147. // we have been disconnected
  148. DetachMonitorConnection();
  149. return TRUE;
  150. }
  151. return FALSE;
  152. #else
  153. return TRUE;
  154. #endif
  155. }
  156. //-----------------------------------------------------------------------------
  157. //
  158. //-----------------------------------------------------------------------------
  159. BOOL
  160. D3DDebugMonitor::IsEventBreak( UINT32 EventType )
  161. {
  162. BOOL bReturn = FALSE;
  163. #define _D3DDM_EVENT_CASE( _Event) \
  164. case D3DDM_EVENT_##_Event: if (MonitorEventBP() & D3DDM_EVENT_##_Event) { bReturn = TRUE; } break
  165. // keep this as single line per event - convenient place to set debugger breakpoints
  166. switch ( EventType )
  167. {
  168. _D3DDM_EVENT_CASE(RSTOKEN);
  169. _D3DDM_EVENT_CASE(BEGINSCENE);
  170. _D3DDM_EVENT_CASE(ENDSCENE);
  171. _D3DDM_EVENT_CASE(VERTEX);
  172. _D3DDM_EVENT_CASE(VERTEXSHADERINST);
  173. _D3DDM_EVENT_CASE(PRIMITIVE);
  174. _D3DDM_EVENT_CASE(PIXEL);
  175. _D3DDM_EVENT_CASE(PIXELSHADERINST);
  176. default: break;
  177. }
  178. return bReturn;
  179. }
  180. //-----------------------------------------------------------------------------
  181. //
  182. //-----------------------------------------------------------------------------
  183. HRESULT
  184. D3DDebugMonitor::MonitorBreakpoint( void )
  185. {
  186. CheckLostMonitorConnection();
  187. if ( !MonitorConnected() ) return S_OK;
  188. // tell monitor that we are at an event breakpoint
  189. SetEvent( m_hTgtEventBP );
  190. DPFINFO("D3DDebugTarget - stopped in debug monitor");
  191. // spin here responding to commands until command given to go
  192. BOOL bResume = FALSE;
  193. while ( !bResume )
  194. {
  195. // wait for command to be issued (or monitor dropped)
  196. WaitForSingleObject( m_hMonEventCmd, INFINITE );
  197. if ( CheckLostMonitorConnection() )
  198. {
  199. bResume = TRUE;
  200. break;
  201. }
  202. // process command
  203. switch ( m_pMonCtx->Command & D3DDM_CMD_MASK )
  204. {
  205. case D3DDM_CMD_GO:
  206. m_pTgtCtx->CommandBufferSize = 0;
  207. bResume = TRUE;
  208. break;
  209. default:
  210. ProcessMonitorCommand();
  211. break;
  212. }
  213. // acknowledge command processing done
  214. SetEvent( m_hTgtEventAck );
  215. }
  216. DPFINFO("D3DDebugTarget - resumed");
  217. return S_OK;
  218. }
  219. ///////////////////////////////////////////////////////////////////////////////
  220. // end