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.

453 lines
17 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 2000.
  3. //
  4. // rddmon.cpp
  5. //
  6. // Reference Device Debug Monitor
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. // converts correctly for pre-snapped floats only
  12. #define FLOATtoNDOT4( _fVal ) ((INT32)((_fVal)*16.))
  13. //-----------------------------------------------------------------------------
  14. //
  15. //-----------------------------------------------------------------------------
  16. RDDebugMonitor::RDDebugMonitor( RefDev* pRD, BOOL bDbgMonConnectionEnabled )
  17. {
  18. m_pRD = pRD;
  19. UINT i;
  20. m_bDbgMonConnectionEnabled = bDbgMonConnectionEnabled;
  21. m_ScreenMask[0] = 0xFFFFFFFF; //0xcccccccc;
  22. m_ScreenMask[1] = 0xFFFFFFFF; //0xcccccccc;
  23. memset( (void*)&m_ShMemI, 0, sizeof(m_ShMemI) );
  24. m_NumShMemI = 0;
  25. }
  26. //-----------------------------------------------------------------------------
  27. RDDebugMonitor::~RDDebugMonitor( void )
  28. {
  29. for (UINT i=0; i<m_NumShMemI; i++)
  30. {
  31. if (m_ShMemI[i].pSM) delete m_ShMemI[i].pSM;
  32. }
  33. }
  34. //-----------------------------------------------------------------------------
  35. void
  36. RDDebugMonitor::NextEvent( UINT32 EventType )
  37. {
  38. CheckLostMonitorConnection();
  39. BOOL bBreakpoint = D3DDebugMonitor::IsEventBreak( EventType );
  40. // do event-specific stuff (state update; actions; check for breakpoints)
  41. UINT i;
  42. switch ( EventType )
  43. {
  44. case D3DDM_EVENT_RSTOKEN:
  45. switch( m_pRD->m_dwRenderState[D3DRS_DEBUGMONITORTOKEN] )
  46. {
  47. case D3DDMT_ENABLE:
  48. m_bDbgMonConnectionEnabled = TRUE;
  49. break;
  50. case D3DDMT_DISABLE:
  51. if( m_pTgtCtx )
  52. {
  53. DetachMonitorConnection();
  54. }
  55. DPFINFO("D3DDebugTarget - debug monitor connection disabled by target");
  56. m_bDbgMonConnectionEnabled = FALSE;
  57. break;
  58. }
  59. break;
  60. case D3DDM_EVENT_BEGINSCENE:
  61. // try to attach if not attached
  62. if (!MonitorConnected()) AttachToMonitor(1);
  63. break;
  64. case D3DDM_EVENT_ENDSCENE:
  65. m_pTgtCtx->SceneCount++;
  66. {
  67. static DWORD bDoSM = 0;
  68. if (bDoSM)
  69. ShMemIRenderTarget( 0x0, 0 );
  70. }
  71. break;
  72. case D3DDM_EVENT_PRIMITIVE:
  73. m_pTgtCtx->PrimitiveCount++;
  74. if (m_pMonCtx && m_pMonCtx->PrimitiveCountBP)
  75. {
  76. if ( m_pTgtCtx->PrimitiveCount == m_pMonCtx->PrimitiveCountBP )
  77. bBreakpoint = TRUE;
  78. }
  79. break;
  80. case D3DDM_EVENT_PIXEL:
  81. m_pTgtCtx->PixelCount++;
  82. if (m_pMonCtx)
  83. {
  84. if (m_pMonCtx->PixelCountBP)
  85. {
  86. if ( m_pTgtCtx->PixelCount == m_pMonCtx->PixelCountBP )
  87. bBreakpoint = TRUE;
  88. }
  89. if (m_pMonCtx->PixelBPEnable)
  90. {
  91. for (i=0; i<32; i++)
  92. {
  93. if ( (1<<i) & m_pMonCtx->PixelBPEnable )
  94. {
  95. if ( ((UINT)m_pMonCtx->PixelBP[i][0] ==
  96. (UINT)m_pRD->m_Rast.m_iX[m_pRD->m_Rast.m_iPix] ) &&
  97. ((UINT)m_pMonCtx->PixelBP[i][1] ==
  98. (UINT)m_pRD->m_Rast.m_iY[m_pRD->m_Rast.m_iPix] ) )
  99. {
  100. bBreakpoint = TRUE;
  101. }
  102. }
  103. }
  104. }
  105. }
  106. break;
  107. case D3DDM_EVENT_PIXELSHADERINST:
  108. break;
  109. }
  110. // invoke base class to talk to monitor and issue commands
  111. if (bBreakpoint)
  112. {
  113. m_pTgtCtx->EventStatus = EventType;
  114. D3DDebugMonitor::MonitorBreakpoint();
  115. m_pTgtCtx->EventStatus = 0x0;
  116. }
  117. return;
  118. }
  119. HRESULT
  120. RDDebugMonitor::ProcessMonitorCommand( void )
  121. {
  122. UINT32 Command = m_pMonCtx->Command;
  123. UINT i;
  124. RefRast* pRast = &m_pRD->m_Rast;
  125. // default case - no data
  126. UINT32 IncomingCommandBufferSize = m_pTgtCtx->CommandBufferSize;
  127. m_pTgtCtx->CommandBufferSize = 0;
  128. switch ( Command & D3DDM_CMD_MASK )
  129. {
  130. case D3DDM_CMD_GETDEVICESTATE:
  131. {
  132. D3DDMDeviceState* pDS = (D3DDMDeviceState*)m_pCmdData;
  133. memcpy( pDS->RenderState, m_pRD->m_dwRenderState, 4*D3DHAL_MAX_RSTATES );
  134. for (i=0; i<D3DHAL_TSS_MAXSTAGES; i++)
  135. {
  136. memcpy( pDS->TextureStageState[i],
  137. m_pRD->m_TextureStageState[i].m_dwVal, 4*D3DTSS_MAX );
  138. }
  139. pDS->VertexShaderHandle = m_pRD->m_CurrentVShaderHandle;
  140. pDS->PixelShaderHandle = m_pRD->m_CurrentPShaderHandle;
  141. pDS->MaxVShaderHandle = (UINT)m_pRD->m_VShaderHandleArray.GetSize();
  142. if (pDS->MaxVShaderHandle) pDS->MaxVShaderHandle -= 1;
  143. while ( ( pDS->MaxVShaderHandle > 0 ) &&
  144. ( NULL == m_pRD->m_VShaderHandleArray[pDS->MaxVShaderHandle].m_pShader ) )
  145. {
  146. pDS->MaxVShaderHandle--;
  147. }
  148. pDS->MaxPShaderHandle = (UINT)m_pRD->m_PShaderHandleArray.GetSize();
  149. if (pDS->MaxPShaderHandle) pDS->MaxPShaderHandle -= 1;
  150. while ( ( pDS->MaxPShaderHandle > 0 ) &&
  151. ( NULL == m_pRD->m_PShaderHandleArray[pDS->MaxPShaderHandle].m_pShader ) )
  152. {
  153. pDS->MaxPShaderHandle--;
  154. }
  155. m_pTgtCtx->CommandBufferSize = sizeof(D3DDMDeviceState);
  156. }
  157. break;
  158. case D3DDM_CMD_GETVERTEXSHADER:
  159. {
  160. DWORD Handle = *(DWORD*)m_pCmdData;
  161. if ( !(Handle & D3DFVF_RESERVED0) ) break;
  162. if ( !m_pRD->m_VShaderHandleArray.IsValidIndex(Handle) ) break;
  163. RDVShader* pRDVS = m_pRD->m_VShaderHandleArray[Handle].m_pShader;
  164. if ( !pRDVS) break;
  165. D3DDMVertexShader* pVS = (D3DDMVertexShader*)m_pCmdData;
  166. m_pTgtCtx->CommandBufferSize = sizeof(D3DDMVertexShader);
  167. }
  168. break;
  169. case D3DDM_CMD_GETVERTEXSTATE:
  170. {
  171. D3DDMVertexState* pVSS = (D3DDMVertexState*)m_pCmdData;
  172. m_pRD->GetVM().GetData( D3DSPR_INPUT, 0, D3DDM_MAX_VSINPUTREG, (void*)(pVSS->InputRegs) );
  173. m_pTgtCtx->CommandBufferSize = sizeof(D3DDMVertexState);
  174. }
  175. break;
  176. case D3DDM_CMD_GETVERTEXSHADERCONST:
  177. {
  178. D3DDMVertexShaderConst* pVSC = (D3DDMVertexShaderConst*)m_pCmdData;
  179. m_pRD->GetVM().GetData( D3DSPR_CONST, 0, 96, (void*)(pVSC->ConstRegs) );
  180. m_pTgtCtx->CommandBufferSize = 96*4*sizeof(FLOAT);
  181. }
  182. break;
  183. case D3DDM_CMD_GETVERTEXSHADERINST:
  184. {
  185. DWORD Handle = *(DWORD*)m_pCmdData;
  186. if ( !(Handle & D3DFVF_RESERVED0) ) break;
  187. if ( !m_pRD->m_VShaderHandleArray.IsValidIndex(Handle) ) break;
  188. RDVShader* pRDVS = m_pRD->m_VShaderHandleArray[Handle].m_pShader;
  189. if ( !pRDVS ) break;
  190. RDVShaderCode* pShC = pRDVS->m_pCode;
  191. UINT Inst = (Command & 0xffff);
  192. if (pShC && (Inst < pShC->GetInstructionCount()))
  193. {
  194. D3DDMVertexShaderInst* pVSI = (D3DDMVertexShaderInst*)m_pCmdData;
  195. memcpy( pVSI->Inst, pShC->m_pInst[Inst].m_Tokens, RD_MAX_SHADERTOKENSPERINST );
  196. memcpy( pVSI->InstString, pShC->m_pInst[Inst].m_String, RD_MAX_SHADERINSTSTRING );
  197. m_pTgtCtx->CommandBufferSize = sizeof(D3DDMVertexShaderInst);
  198. if (pShC->m_pInst[Inst].m_CommentSize)
  199. {
  200. memcpy( (void*)(pVSI+1), pShC->m_pInst[Inst].m_pComment, 4*pShC->m_pInst[Inst].m_CommentSize );
  201. m_pTgtCtx->CommandBufferSize += 4*pShC->m_pInst[Inst].m_CommentSize;
  202. }
  203. }
  204. }
  205. break;
  206. case D3DDM_CMD_GETVERTEXSHADERSTATE:
  207. {
  208. D3DDMVertexShaderState* pVSS = (D3DDMVertexShaderState*)m_pCmdData;
  209. pVSS->CurrentInst = m_pRD->GetVM().GetCurrentInstIndex();
  210. m_pRD->GetVM().GetData( D3DSPR_TEMP, 0, D3DDM_MAX_VSTEMPREG, (void*)(pVSS->TempRegs) );
  211. m_pRD->GetVM().GetData( D3DSPR_RASTOUT, 0, D3DDM_MAX_VSRASTOUTREG, (void*)(pVSS->RastOutRegs) );
  212. m_pRD->GetVM().GetData( D3DSPR_ATTROUT, 0, D3DDM_MAX_VSATTROUTREG, (void*)(pVSS->AttrOutRegs) );
  213. m_pRD->GetVM().GetData( D3DSPR_TEXCRDOUT, 0, D3DDM_MAX_VSTEXCRDOUTREG, (void*)(pVSS->TexCrdOutRegs) );
  214. m_pRD->GetVM().GetData( D3DSPR_ADDR, 0, 1, (void*)(pVSS->AddressReg) );
  215. m_pTgtCtx->CommandBufferSize = sizeof(D3DDMVertexShaderState);
  216. }
  217. break;
  218. case D3DDM_CMD_GETPIXELSTATE:
  219. {
  220. D3DDMPixelState* pPS = (D3DDMPixelState*)m_pCmdData;
  221. UINT iPix = (Command & 0xffff);
  222. if (pRast->m_bPixelIn[iPix])
  223. {
  224. pPS->Location[0] = pRast->m_iX[iPix];
  225. pPS->Location[1] = pRast->m_iY[iPix];
  226. pPS->Depth = pRast->m_Depth[iPix];
  227. pPS->FogIntensity = pRast->m_FogIntensity[iPix];
  228. memcpy( pPS->InputRegs[0], pRast->m_InputReg[0][iPix], 16 );
  229. memcpy( pPS->InputRegs[1], pRast->m_InputReg[1][iPix], 16 );
  230. m_pTgtCtx->CommandBufferSize = sizeof(D3DDMPixelState);
  231. }
  232. }
  233. break;
  234. case D3DDM_CMD_GETPIXELSHADERCONST:
  235. {
  236. D3DDMPixelShaderConst* pPSC = (D3DDMPixelShaderConst*)m_pCmdData;
  237. memcpy( pPSC->ConstRegs[0], pRast->m_ConstReg[0][0], 16 );
  238. memcpy( pPSC->ConstRegs[1], pRast->m_ConstReg[1][0], 16 );
  239. memcpy( pPSC->ConstRegs[2], pRast->m_ConstReg[2][0], 16 );
  240. memcpy( pPSC->ConstRegs[3], pRast->m_ConstReg[3][0], 16 );
  241. memcpy( pPSC->ConstRegs[4], pRast->m_ConstReg[4][0], 16 );
  242. memcpy( pPSC->ConstRegs[5], pRast->m_ConstReg[5][0], 16 );
  243. memcpy( pPSC->ConstRegs[6], pRast->m_ConstReg[6][0], 16 );
  244. memcpy( pPSC->ConstRegs[7], pRast->m_ConstReg[7][0], 16 );
  245. m_pTgtCtx->CommandBufferSize = sizeof(D3DDMPixelShaderConst);
  246. }
  247. break;
  248. case D3DDM_CMD_GETPIXELSHADERINST:
  249. {
  250. DWORD Handle = *(DWORD*)m_pCmdData;
  251. if ( !m_pRD->m_PShaderHandleArray.IsValidIndex(Handle) ) break;
  252. RDPShader* pRDPS = m_pRD->m_PShaderHandleArray[Handle].m_pShader;
  253. if ( !pRDPS ) break;
  254. D3DDMPixelShaderInst* pPSI = (D3DDMPixelShaderInst*)m_pCmdData;
  255. UINT Inst = (Command & 0xffff);
  256. if ( Inst < pRDPS->m_cInst )
  257. {
  258. PixelShaderInstruction* pInst = pRDPS->m_pInst+Inst;
  259. pPSI->Inst[0] = pInst->Opcode;
  260. pPSI->Inst[1] = pInst->DstParam;
  261. pPSI->Inst[2] = pInst->SrcParam[0];
  262. pPSI->Inst[3] = pInst->SrcParam[1];
  263. pPSI->Inst[4] = pInst->SrcParam[2];
  264. memcpy( pPSI->InstString, pInst->Text, RD_MAX_SHADERINSTSTRING );
  265. m_pTgtCtx->CommandBufferSize = sizeof(D3DDMPixelShaderInst);
  266. if (pInst->CommentSize)
  267. {
  268. memcpy( (void*)(pPSI+1), pInst->pComment, 4*pInst->CommentSize );
  269. m_pTgtCtx->CommandBufferSize += 4*pInst->CommentSize;
  270. }
  271. }
  272. else
  273. {
  274. m_pTgtCtx->CommandBufferSize = 0;
  275. }
  276. }
  277. break;
  278. case D3DDM_CMD_GETPIXELSHADERSTATE:
  279. {
  280. D3DDMPixelShaderState* pPSS = (D3DDMPixelShaderState*)m_pCmdData;
  281. UINT iPix = (Command & 0xffff);
  282. pPSS->CurrentInst = pRast->m_CurrentPSInst;
  283. pPSS->Discard = pRast->m_bPixelDiscard[iPix];
  284. memcpy( pPSS->TempRegs[0], pRast->m_TempReg[0][iPix], 16 );
  285. memcpy( pPSS->TempRegs[1], pRast->m_TempReg[1][iPix], 16 );
  286. memcpy( pPSS->TextRegs[0], pRast->m_TextReg[0][iPix], 16 );
  287. memcpy( pPSS->TextRegs[1], pRast->m_TextReg[1][iPix], 16 );
  288. memcpy( pPSS->TextRegs[2], pRast->m_TextReg[2][iPix], 16 );
  289. memcpy( pPSS->TextRegs[3], pRast->m_TextReg[3][iPix], 16 );
  290. memcpy( pPSS->TextRegs[4], pRast->m_TextReg[4][iPix], 16 );
  291. memcpy( pPSS->TextRegs[5], pRast->m_TextReg[5][iPix], 16 );
  292. memcpy( pPSS->TextRegs[6], pRast->m_TextReg[6][iPix], 16 );
  293. memcpy( pPSS->TextRegs[7], pRast->m_TextReg[7][iPix], 16 );
  294. m_pTgtCtx->CommandBufferSize = sizeof(D3DDMPixelShaderState);
  295. }
  296. break;
  297. case D3DDM_CMD_DUMPTEXTURE:
  298. {
  299. int iSMI = (Command>>0)&0xf;
  300. int iSTG = (Command>>4)&0x7;
  301. int iLOD = (Command>>7)&0xf;
  302. int iIDX = (Command>>11)&0x1f;
  303. ShMemISurface2D( m_pRD->m_pTexture[iSTG], iLOD, 0x0, iSMI );
  304. }
  305. break;
  306. case D3DDM_CMD_DUMPRENDERTARGET:
  307. {
  308. int iSMI = (Command>>0)&0xf;
  309. ShMemIRenderTarget( 0x0, iSMI );
  310. break;
  311. }
  312. break;
  313. }
  314. return S_OK;
  315. }
  316. //-----------------------------------------------------------------------------
  317. //
  318. //-----------------------------------------------------------------------------
  319. void
  320. RDDebugMonitor::GrowShMemArray( UINT ShMemI )
  321. {
  322. if (ShMemI >= D3DDM_IMAGE_MAX) return; // too many
  323. if (ShMemI < m_NumShMemI) return; // already there
  324. UINT OldSmMemI = m_NumShMemI ? m_NumShMemI-1 : 0;
  325. m_NumShMemI = ShMemI+1;
  326. memset( (void*)&m_ShMemI, 0, sizeof(m_ShMemI) );
  327. for ( UINT i=OldSmMemI; i<m_NumShMemI; i++)
  328. {
  329. m_ShMemI[i].W = 400;
  330. m_ShMemI[i].H = 400;
  331. m_ShMemI[i].BPP = 4;
  332. m_ShMemI[i].SF = RD_SF_B8G8R8A8;
  333. m_ShMemI[i].pSM = new D3DSharedMem(
  334. 16 + m_ShMemI[i].W*m_ShMemI[i].H*m_ShMemI[i].BPP,
  335. D3DDM_IMAGE_SM "%d", i );
  336. m_ShMemI[i].pBits = (void*)((char*)m_ShMemI[i].pSM->GetPtr()+16);
  337. *((DWORD*)m_ShMemI[i].pSM->GetPtr()+0) = m_ShMemI[i].W;
  338. *((DWORD*)m_ShMemI[i].pSM->GetPtr()+1) = m_ShMemI[i].H;
  339. *((DWORD*)m_ShMemI[i].pSM->GetPtr()+2) = m_ShMemI[i].BPP;
  340. *((DWORD*)m_ShMemI[i].pSM->GetPtr()+3) = m_ShMemI[i].SF;
  341. }
  342. }
  343. //-----------------------------------------------------------------------------
  344. //
  345. // Dumps render target image to specified shared memory segment. Viewable by
  346. // rddm_iview image viewer tool.
  347. //
  348. //-----------------------------------------------------------------------------
  349. void
  350. RDDebugMonitor::ShMemIRenderTarget( DWORD Flags, UINT iSM )
  351. {
  352. GrowShMemArray( iSM );
  353. // copy to debug monitor shared memory
  354. int height = (int)min(
  355. (int)m_pRD->m_pRenderTarget->m_pColor->GetHeight(),
  356. (int)m_ShMemI[iSM].H);
  357. int width = (int)min(
  358. (int)m_pRD->m_pRenderTarget->m_pColor->GetWidth(),
  359. (int)m_ShMemI[iSM].W);
  360. for (int iY = 0; iY < height; iY++)
  361. {
  362. for (int iX = 0; iX < width; iX++)
  363. {
  364. RDColor Color((UINT32)0);
  365. if( m_pRD->m_pRenderTarget->m_pColor->m_iSamples == 0 )
  366. {
  367. m_pRD->m_pRenderTarget->ReadPixelColor( iX, iY, 0, Color );
  368. }
  369. else
  370. {
  371. FLOAT fSampleScale = 1.F/((FLOAT)m_pRD->m_pRenderTarget->m_pColor->m_iSamples);
  372. for (UINT iS=0; iS<m_pRD->m_pRenderTarget->m_pColor->m_iSamples; iS++)
  373. {
  374. RDColor SampleColor;
  375. m_pRD->m_pRenderTarget->ReadPixelColor( iX, iY, iS, SampleColor );
  376. Color.R += (SampleColor.R * fSampleScale);
  377. Color.G += (SampleColor.G * fSampleScale);
  378. Color.B += (SampleColor.B * fSampleScale);
  379. Color.A += (SampleColor.A * fSampleScale);
  380. }
  381. }
  382. Color.ConvertTo( m_ShMemI[iSM].SF, 0.,
  383. (char*)m_ShMemI[iSM].pBits +
  384. (m_ShMemI[iSM].W*m_ShMemI[iSM].BPP*iY) + (m_ShMemI[iSM].BPP*iX) );
  385. }
  386. }
  387. {
  388. char winstr[128]; _snprintf( winstr, 128, "D3DDM_I_%d", iSM );
  389. HWND hWnd = FindWindow( winstr, winstr );
  390. if (NULL != hWnd) SendMessage(hWnd, WM_USER, 0, 0);
  391. }
  392. }
  393. //-----------------------------------------------------------------------------
  394. //
  395. //-----------------------------------------------------------------------------
  396. void
  397. RDDebugMonitor::ShMemISurface2D( RDSurface2D* pRS, INT32 iLOD, DWORD Flags, UINT iSM )
  398. {
  399. GrowShMemArray( iSM );
  400. if (!pRS) return;
  401. // copy to debug monitor shared memory
  402. int height = (int)min(pRS->m_iHeight,(int)m_ShMemI[iSM].H);
  403. int width = (int)min(pRS->m_iWidth,(int)m_ShMemI[iSM].W);
  404. for (int iY = 0; iY < height; iY++)
  405. {
  406. for (int iX = 0; iX < width; iX++)
  407. {
  408. RDColor Color; BOOL bDummy; pRS->ReadColor( iX, iY, 0, iLOD, Color, bDummy );
  409. Color.ConvertTo( m_ShMemI[iSM].SF, 0.,
  410. (char*)m_ShMemI[iSM].pBits +
  411. (m_ShMemI[iSM].W*m_ShMemI[iSM].BPP*iY) + (m_ShMemI[iSM].BPP*iX) );
  412. }
  413. }
  414. {
  415. char winstr[128]; _snprintf( winstr, 128, "D3DDM_I_%d", iSM );
  416. HWND hWnd = FindWindow( winstr, winstr );
  417. if (NULL != hWnd) SendMessage(hWnd, WM_USER, 0, 0);
  418. }
  419. }
  420. ///////////////////////////////////////////////////////////////////////////////
  421. // end