Leaked source code of windows server 2003
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.

1036 lines
34 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 2000.
  3. //
  4. // refdev.cpp
  5. //
  6. // Direct3D Reference Device - public interfaces
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. // This is a global static array of the block sizes in bytes for the
  12. // various DXTn compression formats
  13. int g_DXTBlkSize[NUM_DXT_FORMATS] =
  14. {
  15. sizeof(DXTBlockRGB),
  16. sizeof(DXTBlockAlpha4),
  17. sizeof(DXTBlockAlpha4),
  18. sizeof(DXTBlockAlpha3),
  19. sizeof(DXTBlockAlpha3),
  20. };
  21. //-----------------------------------------------------------------------------
  22. //
  23. // Memory management function installation
  24. //
  25. //-----------------------------------------------------------------------------
  26. // global pointers to memory allocation functions (used through MEM* macros)
  27. LPVOID (__cdecl *g_pfnMemAlloc)( size_t size ) = NULL;
  28. void (__cdecl *g_pfnMemFree)( LPVOID lptr ) = NULL;
  29. LPVOID (__cdecl *g_pfnMemReAlloc)( LPVOID ptr, size_t size ) = NULL;
  30. // install memory management functions - must be called before instancing
  31. // rasterizer object
  32. void RefRastSetMemif(
  33. LPVOID(__cdecl *pfnMemAlloc)(size_t),
  34. void(__cdecl *pfnMemFree)(LPVOID),
  35. LPVOID(__cdecl *pfnMemReAlloc)(LPVOID,size_t))
  36. {
  37. DPFRR(1, "RefRastSetMemif %08x %08x %08x\n",
  38. pfnMemAlloc,pfnMemFree,pfnMemReAlloc);
  39. g_pfnMemAlloc = pfnMemAlloc;
  40. g_pfnMemFree = pfnMemFree;
  41. g_pfnMemReAlloc = pfnMemReAlloc;
  42. }
  43. ///////////////////////////////////////////////////////////////////////////////
  44. // //
  45. // Public Interface Methods //
  46. // //
  47. ///////////////////////////////////////////////////////////////////////////////
  48. //-----------------------------------------------------------------------------
  49. //
  50. // SetRenderTarget -
  51. //
  52. //-----------------------------------------------------------------------------
  53. void
  54. RefDev::SetRenderTarget( RDRenderTarget* pRenderTarget )
  55. {
  56. m_pRenderTarget = pRenderTarget;
  57. // update the W scaling values for mapping interpolated W's into buffer range
  58. m_fWBufferNorm[0] = pRenderTarget->m_fWRange[0];
  59. FLOAT fWRange = pRenderTarget->m_fWRange[1] - pRenderTarget->m_fWRange[0];
  60. m_fWBufferNorm[1] = ( 0. != fWRange ) ? ( 1./fWRange ) : ( 1. );
  61. }
  62. //-----------------------------------------------------------------------------
  63. //
  64. // SetTextureStageState -
  65. //
  66. //-----------------------------------------------------------------------------
  67. // map DX6(&7) texture filtering enums to DX8 enums
  68. static DWORD
  69. MapDX6toDX8TexFilter( DWORD dwStageState, DWORD dwValue )
  70. {
  71. switch (dwStageState)
  72. {
  73. case D3DTSS_MAGFILTER:
  74. switch (dwValue)
  75. {
  76. case D3DTFG_POINT : return D3DTEXF_POINT;
  77. case D3DTFG_LINEAR : return D3DTEXF_LINEAR;
  78. case D3DTFG_FLATCUBIC : return D3DTEXF_FLATCUBIC;
  79. case D3DTFG_GAUSSIANCUBIC : return D3DTEXF_GAUSSIANCUBIC;
  80. case D3DTFG_ANISOTROPIC : return D3DTEXF_ANISOTROPIC;
  81. }
  82. break;
  83. case D3DTSS_MINFILTER:
  84. switch (dwValue)
  85. {
  86. case D3DTFN_POINT : return D3DTEXF_POINT;
  87. case D3DTFN_LINEAR : return D3DTEXF_LINEAR;
  88. case D3DTFN_ANISOTROPIC : return D3DTEXF_ANISOTROPIC;
  89. }
  90. break;
  91. case D3DTSS_MIPFILTER:
  92. switch (dwValue)
  93. {
  94. case D3DTFP_NONE : return D3DTEXF_NONE;
  95. case D3DTFP_POINT : return D3DTEXF_POINT;
  96. case D3DTFP_LINEAR : return D3DTEXF_LINEAR;
  97. }
  98. break;
  99. }
  100. return 0x0;
  101. }
  102. void
  103. RefDev::SetTextureStageState(
  104. DWORD dwStage, DWORD dwStageState, DWORD dwValue )
  105. {
  106. // check for range before continuing
  107. if ( dwStage >= D3DHAL_TSS_MAXSTAGES)
  108. {
  109. return;
  110. }
  111. if (dwStageState > D3DTSS_MAX)
  112. {
  113. return;
  114. }
  115. // set in internal per-stage state
  116. m_TextureStageState[dwStage].m_dwVal[dwStageState] = dwValue;
  117. m_dwRastFlags |= RDRF_TEXTURESTAGESTATE_CHANGED;
  118. switch ( dwStageState )
  119. {
  120. case D3DTSS_TEXTUREMAP:
  121. // bind texture indicated by handle to m_pTexture array
  122. if (IsDriverDX6AndBefore() || IsInterfaceDX6AndBefore())
  123. {
  124. // This is the legacy behavior (prev. to DX7)
  125. MapTextureHandleToDevice( dwStage );
  126. }
  127. else
  128. {
  129. // This is the new behavior (DX7 and beyond)
  130. SetTextureHandle( dwStage, dwValue );
  131. }
  132. m_dwRastFlags |= RDRF_LEGACYPIXELSHADER_CHANGED;
  133. break;
  134. case D3DTSS_COLOROP:
  135. m_dwRastFlags |= RDRF_LEGACYPIXELSHADER_CHANGED;
  136. break;
  137. // not including legacy headers, so don't have D3DTSS_ADDRESS
  138. // case D3DTSS_ADDRESS:
  139. // // map single set ADDRESS to U, V controls (pre-DX8 interfaces only)
  140. // m_TextureStageState[dwStage].m_dwVal[D3DTSS_ADDRESSU] = dwValue;
  141. // m_TextureStageState[dwStage].m_dwVal[D3DTSS_ADDRESSV] = dwValue;
  142. // break;
  143. case D3DTSS_MAGFILTER:
  144. case D3DTSS_MINFILTER:
  145. case D3DTSS_MIPFILTER:
  146. if ( IsDriverDX7AndBefore() )
  147. {
  148. m_TextureStageState[dwStage].m_dwVal[dwStageState]
  149. = MapDX6toDX8TexFilter( dwStageState, dwValue );
  150. }
  151. break;
  152. }
  153. }
  154. //-----------------------------------------------------------------------------
  155. //
  156. // TextureCreate - Instantiates new RDSurface2D object, computes texture handle
  157. // to associate with it, and returns both to caller. Note that texture handle
  158. // is a pointer and can be used to get at the corresponding texture object.
  159. //
  160. //-----------------------------------------------------------------------------
  161. BOOL
  162. RefDev::TextureCreate(
  163. LPD3DTEXTUREHANDLE phTex, RDSurface2D** ppTex )
  164. {
  165. // allocate internal texture structure
  166. *ppTex = new RDSurface2D();
  167. _ASSERTa( NULL != *ppTex, "new failure on texture create", return FALSE; );
  168. // use separately allocated pointer for handle
  169. RDSurface2D** ppTexForHandle = (RDSurface2D**)MEMALLOC( sizeof(RDSurface2D*) );
  170. _ASSERTa( NULL != ppTexForHandle, "malloc failure on texture create", return FALSE; );
  171. *ppTexForHandle = *ppTex;
  172. // return texture handle
  173. (*ppTex)->m_hTex = (ULONG_PTR)ppTexForHandle;
  174. *phTex = (*ppTex)->m_hTex;
  175. return TRUE;
  176. }
  177. //-----------------------------------------------------------------------------
  178. //
  179. // TextureDestroy -
  180. //
  181. //-----------------------------------------------------------------------------
  182. BOOL
  183. RefDev::TextureDestroy( D3DTEXTUREHANDLE hTex )
  184. {
  185. // first check if texture about to be destroyed is mapped - if so then
  186. // unmap it
  187. for ( int iStage=0; iStage<D3DHAL_TSS_MAXSTAGES; iStage++ )
  188. {
  189. if ( hTex == m_TextureStageState[iStage].m_dwVal[D3DTSS_TEXTUREMAP] )
  190. {
  191. SetTextureStageState( iStage, D3DTSS_TEXTUREMAP, 0x0 );
  192. }
  193. }
  194. // resolve handle to RDSurface2D pointer
  195. RDSurface2D* pTex = MapHandleToTexture( hTex );
  196. if ( NULL == pTex ) { return FALSE; }
  197. // free the handle pointer
  198. #ifdef _IA64_
  199. _ASSERTa(FALSE, "This will not work on IA64", return FALSE;);
  200. #endif
  201. RDSurface2D** ppTex = (RDSurface2D**)ULongToPtr(hTex);
  202. if ( NULL != ppTex) { MEMFREE( ppTex ); }
  203. // free the RDSurface2D
  204. delete pTex;
  205. return TRUE;
  206. }
  207. //-----------------------------------------------------------------------------
  208. //
  209. // TextureGetSurf -
  210. //
  211. //-----------------------------------------------------------------------------
  212. DWORD
  213. RefDev::TextureGetSurf( D3DTEXTUREHANDLE hTex )
  214. {
  215. RDSurface2D* pTex = MapHandleToTexture(hTex);
  216. if ( NULL == pTex ) { return 0x0; }
  217. return PtrToUlong( pTex->m_pDDSLcl[0] );
  218. }
  219. //-----------------------------------------------------------------------------
  220. //
  221. // GetCurrentTextureMaps - This function fills in a passed array texture handles
  222. // and pointers. The array should be sized by D3DHAL_TSS_MAXSTAGES.
  223. //
  224. // This is used to facilitate external locking/unlocking of surfaces used for
  225. // textures.
  226. //
  227. //-----------------------------------------------------------------------------
  228. int
  229. RefDev::GetCurrentTextureMaps(
  230. D3DTEXTUREHANDLE *phTex, RDSurface2D** pTex)
  231. {
  232. UpdateActiveTexStageCount();
  233. for ( int i=0; i<m_cActiveTextureStages; i++ )
  234. {
  235. if ( NULL == m_pTexture[i] )
  236. {
  237. phTex[i] = 0x0;
  238. pTex[i] = NULL;
  239. }
  240. else
  241. {
  242. phTex[i] = m_pTexture[i]->m_hTex;
  243. pTex[i] = m_pTexture[i];
  244. }
  245. }
  246. return m_cActiveTextureStages;
  247. }
  248. //-----------------------------------------------------------------------------
  249. //
  250. // SceneCapture - Used to trigger fragment buffer resolve.
  251. //
  252. //-----------------------------------------------------------------------------
  253. //#define DO_SCENE_RENDER_TIME
  254. #ifdef DO_SCENE_RENDER_TIME
  255. #include <mmsystem.h>
  256. #endif
  257. void
  258. RefDev::SceneCapture( DWORD dwFlags )
  259. {
  260. static INT32 iScene = 0;
  261. static INT32 iLastSceneEnd = 0;
  262. #ifdef DO_SCENE_RENDER_TIME
  263. static DWORD timeBS = 0;
  264. #endif
  265. switch (dwFlags)
  266. {
  267. case D3DHAL_SCENE_CAPTURE_START:
  268. iScene++;
  269. #ifdef DO_SCENE_RENDER_TIME
  270. timeBS = timeGetTime();
  271. #endif
  272. break;
  273. case D3DHAL_SCENE_CAPTURE_END:
  274. if (iScene == iLastSceneEnd) break; // getting multiple END per BEGIN
  275. iLastSceneEnd = iScene;
  276. #ifdef DO_SCENE_RENDER_TIME
  277. {
  278. DWORD timeES = timeGetTime();
  279. FLOAT dt = (FLOAT)(timeES - timeBS)/1000.f;
  280. timeBS = 0;
  281. RDDebugPrintf("SceneRenderTime: %f", dt );
  282. }
  283. #endif
  284. break;
  285. }
  286. }
  287. //-----------------------------------------------------------------------------
  288. //
  289. // Query functions to get pointer to current render target and render state.
  290. //
  291. //-----------------------------------------------------------------------------
  292. RDRenderTarget*
  293. RefDev::GetRenderTarget(void)
  294. {
  295. return m_pRenderTarget;
  296. }
  297. //-----------------------------------------------------------------------------
  298. //
  299. //-----------------------------------------------------------------------------
  300. HRESULT
  301. RefDev::UpdateRastState( void )
  302. {
  303. // check 'dirty' flags
  304. if (m_dwRastFlags & RDRF_MULTISAMPLE_CHANGED)
  305. {
  306. // update multi-sample RS related state
  307. m_Rast.SetSampleMode(
  308. m_pRenderTarget->m_pColor->m_iSamples,
  309. m_dwRenderState[D3DRS_MULTISAMPLEANTIALIAS] );
  310. m_Rast.SetSampleMask(
  311. m_dwRenderState[D3DRS_MULTISAMPLEMASK] );
  312. m_dwRastFlags &= ~(RDRF_MULTISAMPLE_CHANGED);
  313. }
  314. if (m_dwRastFlags & RDRF_PIXELSHADER_CHANGED)
  315. {
  316. if (m_CurrentPShaderHandle)
  317. {
  318. m_Rast.m_pCurrentPixelShader =
  319. GetPShader(m_CurrentPShaderHandle);
  320. m_Rast.m_bLegacyPixelShade = FALSE;
  321. }
  322. else
  323. {
  324. // legacy pixel shader
  325. m_Rast.UpdateLegacyPixelShader();
  326. m_Rast.m_pCurrentPixelShader = m_Rast.m_pLegacyPixelShader;
  327. m_Rast.m_bLegacyPixelShade = TRUE;
  328. }
  329. UpdateActiveTexStageCount();
  330. m_dwRastFlags &= ~(RDRF_PIXELSHADER_CHANGED);
  331. }
  332. if (m_dwRastFlags & RDRF_LEGACYPIXELSHADER_CHANGED)
  333. {
  334. if (m_Rast.m_bLegacyPixelShade)
  335. {
  336. m_Rast.UpdateLegacyPixelShader();
  337. m_Rast.m_pCurrentPixelShader = m_Rast.m_pLegacyPixelShader;
  338. UpdateActiveTexStageCount();
  339. }
  340. m_dwRastFlags &= ~(RDRF_LEGACYPIXELSHADER_CHANGED);
  341. }
  342. if (m_dwRastFlags & RDRF_TEXTURESTAGESTATE_CHANGED)
  343. {
  344. m_Rast.UpdateTextureControls();
  345. m_dwRastFlags &= ~(RDRF_TEXTURESTAGESTATE_CHANGED);
  346. }
  347. return S_OK;
  348. }
  349. //-----------------------------------------------------------------------------
  350. //
  351. // Begin/End bracket functions - Called before/after a list of primitives are
  352. // rendered.
  353. //
  354. //-----------------------------------------------------------------------------
  355. HRESULT
  356. RefDev::BeginRendering( void )
  357. {
  358. // If already in Begin, do nothing
  359. if( m_bInBegin ) return S_OK;
  360. #ifdef _X86_
  361. // save floating point mode and set to extended precision mode
  362. {
  363. WORD wTemp, wSave;
  364. __asm
  365. {
  366. fstcw wSave
  367. mov ax, wSave
  368. or ax, 300h ;; extended precision mode
  369. // and ax, 00FFh ;; single precision mode + round nearest or even
  370. mov wTemp, ax
  371. fldcw wTemp
  372. }
  373. m_wSaveFP = wSave;
  374. }
  375. #endif
  376. m_bInBegin = TRUE;
  377. return S_OK;
  378. }
  379. //-----------------------------------------------------------------------------
  380. HRESULT
  381. RefDev::EndRendering( void )
  382. {
  383. if ( m_bInBegin )
  384. {
  385. #ifdef _X86_
  386. // restore floating point mode
  387. {
  388. WORD wSave = m_wSaveFP;
  389. __asm {fldcw wSave}
  390. }
  391. #endif
  392. m_bInBegin = FALSE;
  393. }
  394. return S_OK;
  395. }
  396. //-----------------------------------------------------------------------------
  397. //
  398. // Clear specified rectangles in the render target
  399. // Directly handles the command from the DP2 stream
  400. //
  401. //-----------------------------------------------------------------------------
  402. HRESULT RefDev::Clear(LPD3DHAL_DP2COMMAND pCmd)
  403. {
  404. D3DHAL_DP2CLEAR *pData = (D3DHAL_DP2CLEAR*)(pCmd + 1);
  405. WORD i;
  406. INT32 x,y;
  407. RDColor fillColor(pData->dwFillColor);
  408. RDDepth fillDepth;
  409. if (m_pRenderTarget->m_pDepth)
  410. {
  411. fillDepth.SetSType(m_pRenderTarget->m_pDepth->GetSurfaceFormat());
  412. }
  413. fillDepth = pData->dvFillDepth;
  414. struct
  415. {
  416. D3DHAL_DP2COMMAND cmd;
  417. D3DHAL_DP2CLEAR data;
  418. } WholeViewport;
  419. if (!(pData->dwFlags & D3DCLEAR_COMPUTERECTS))
  420. {
  421. // Do nothing for non-pure device
  422. }
  423. else
  424. if (pCmd->wStateCount == 0)
  425. {
  426. // When wStateCount is zero we need to clear whole viewport
  427. WholeViewport.cmd = *pCmd;
  428. WholeViewport.cmd.wStateCount = 1;
  429. WholeViewport.data.dwFlags = pData->dwFlags;
  430. WholeViewport.data.dwFillColor = pData->dwFillColor;
  431. WholeViewport.data.dvFillDepth = pData->dvFillDepth;
  432. WholeViewport.data.dwFillStencil = pData->dwFillStencil;
  433. WholeViewport.data.Rects[0].left = m_Clipper.m_Viewport.dwX;
  434. WholeViewport.data.Rects[0].top = m_Clipper.m_Viewport.dwY;
  435. WholeViewport.data.Rects[0].right = m_Clipper.m_Viewport.dwX +
  436. m_Clipper.m_Viewport.dwWidth;
  437. WholeViewport.data.Rects[0].bottom = m_Clipper.m_Viewport.dwY +
  438. m_Clipper.m_Viewport.dwHeight;
  439. // Replace pointers and continue as usual
  440. pCmd = (LPD3DHAL_DP2COMMAND)&WholeViewport;
  441. pData = &WholeViewport.data;
  442. }
  443. else
  444. {
  445. // We need to cull all rects against the current viewport
  446. UINT nRects = pCmd->wStateCount;
  447. // Compute how much memory we need to process rects
  448. UINT NeededSize = sizeof(D3DHAL_DP2COMMAND) +
  449. sizeof(D3DHAL_DP2CLEAR) +
  450. (nRects-1) * sizeof(RECT); // One rect is in DP2CLEAR
  451. HRESULT hr = S_OK;
  452. HR_RET(m_ClearRectBuffer.Grow(NeededSize));
  453. RECT vwport; // Viewport rectangle to cull against
  454. vwport.left = m_Clipper.m_Viewport.dwX;
  455. vwport.top = m_Clipper.m_Viewport.dwY;
  456. vwport.right = m_Clipper.m_Viewport.dwX + m_Clipper.m_Viewport.dwWidth;
  457. vwport.bottom = m_Clipper.m_Viewport.dwY + m_Clipper.m_Viewport.dwHeight;
  458. // Go through input rects and build output rect array
  459. LPRECT pInputRects = pData->Rects;
  460. LPRECT pOutputRects = (LPRECT)(&m_ClearRectBuffer[0] +
  461. sizeof(D3DHAL_DP2COMMAND) +
  462. sizeof(D3DHAL_DP2CLEAR) -
  463. sizeof(RECT));
  464. UINT nOutputRects = 0;
  465. for (UINT i = 0; i < nRects; i++)
  466. {
  467. if (IntersectRect(&pOutputRects[nOutputRects], &vwport,
  468. &pInputRects[i]))
  469. {
  470. nOutputRects++;
  471. }
  472. }
  473. if (nOutputRects == 0)
  474. return S_OK;
  475. // Now replace pCmd and pData pointers and continue as usual
  476. LPD3DHAL_DP2CLEAR pOldData = pData;
  477. LPD3DHAL_DP2COMMAND pOldCmd = pCmd;
  478. pCmd = (LPD3DHAL_DP2COMMAND)&m_ClearRectBuffer[0];
  479. pData = (D3DHAL_DP2CLEAR*)(pCmd + 1);
  480. *pCmd = *pOldCmd;
  481. pCmd->wStateCount = (WORD)nOutputRects;
  482. pData->dwFlags = pOldData->dwFlags;
  483. pData->dwFillColor = pOldData->dwFillColor;
  484. pData->dvFillDepth = pOldData->dvFillDepth;
  485. pData->dwFillStencil = pOldData->dwFillStencil;
  486. }
  487. #ifdef _X86_
  488. // Float to integer conversion routines for 24+ bit buffers work
  489. // only with extended FPU mode.
  490. //
  491. WORD wSaveFP;
  492. // save floating point mode and set to extended precision mode
  493. {
  494. WORD wTemp, wSave;
  495. __asm
  496. {
  497. fstcw wSaveFP
  498. mov ax, wSaveFP
  499. or ax, 300h ;; extended precision mode
  500. mov wTemp, ax
  501. fldcw wTemp
  502. }
  503. }
  504. #endif
  505. if(pData->dwFlags & D3DCLEAR_TARGET)
  506. {
  507. if (m_dwRenderState[D3DRENDERSTATE_DITHERENABLE] == FALSE)
  508. {
  509. m_pRenderTarget->Clear(fillColor, pCmd);
  510. }
  511. else
  512. {
  513. for (i = 0; i < pCmd->wStateCount; i++)
  514. {
  515. for (y = pData->Rects[i].top; y < pData->Rects[i].bottom; ++y)
  516. {
  517. for (x = pData->Rects[i].left; x < pData->Rects[i].right; ++x)
  518. {
  519. m_pRenderTarget->WritePixelColor(x, y, fillColor, TRUE);
  520. }
  521. }
  522. }
  523. }
  524. }
  525. switch (pData->dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL))
  526. {
  527. case (D3DCLEAR_ZBUFFER):
  528. m_pRenderTarget->ClearDepth(fillDepth, pCmd);
  529. break;
  530. case (D3DCLEAR_STENCIL):
  531. m_pRenderTarget->ClearStencil(pData->dwFillStencil, pCmd);
  532. break;
  533. case (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL):
  534. m_pRenderTarget->ClearDepthStencil(fillDepth, pData->dwFillStencil, pCmd);
  535. break;
  536. }
  537. #ifdef _X86_
  538. // restore floating point mode
  539. {
  540. __asm {fldcw wSaveFP}
  541. }
  542. #endif
  543. return D3D_OK;
  544. }
  545. //-----------------------------------------------------------------------------
  546. //
  547. // Clear specified rectangles in the render target
  548. // Directly handles the command from the DP2 stream
  549. //
  550. //-----------------------------------------------------------------------------
  551. void RDRenderTarget::Clear(RDColor fillColor, LPD3DHAL_DP2COMMAND pCmd)
  552. {
  553. LPD3DHAL_DP2CLEAR pData = (LPD3DHAL_DP2CLEAR)(pCmd + 1);
  554. UINT32 dwColor = 0;
  555. fillColor.ConvertTo( m_pColor->GetSurfaceFormat(), 0.5f, (char*)&dwColor);
  556. for (DWORD i = 0; i < pCmd->wStateCount; i++)
  557. {
  558. DWORD x0 = pData->Rects[i].left;
  559. DWORD y0 = pData->Rects[i].top;
  560. DWORD dwWidth = ( pData->Rects[i].right - x0 ) * m_pColor->GetSamples();
  561. DWORD dwHeight = pData->Rects[i].bottom - y0;
  562. char* pSurface = PixelAddress( x0, y0, 0, 0, m_pColor );
  563. switch ( m_pColor->GetSurfaceFormat() )
  564. {
  565. case RD_SF_B8G8R8A8:
  566. case RD_SF_B8G8R8X8:
  567. {
  568. for (DWORD y = dwHeight; y > 0; y--)
  569. {
  570. UINT32 *p = (UINT32*)pSurface;
  571. for (DWORD x = dwWidth; x > 0; x--)
  572. {
  573. *p++ = dwColor;
  574. }
  575. pSurface += m_pColor->GetPitch();
  576. }
  577. }
  578. break;
  579. case RD_SF_B8G8R8:
  580. {
  581. for (DWORD y = dwHeight; y > 0; y--)
  582. {
  583. UINT8 *p = (UINT8*)pSurface;
  584. for (DWORD x = dwWidth; x > 0; x--)
  585. {
  586. *p++ = ((UINT8*)&dwColor)[0];
  587. *p++ = ((UINT8*)&dwColor)[1];
  588. *p++ = ((UINT8*)&dwColor)[2];
  589. }
  590. pSurface += m_pColor->GetPitch();
  591. }
  592. }
  593. break;
  594. case RD_SF_B4G4R4A4:
  595. case RD_SF_B5G6R5:
  596. case RD_SF_B5G5R5A1:
  597. case RD_SF_B5G5R5X1:
  598. {
  599. for (DWORD y = dwHeight; y > 0; y--)
  600. {
  601. UINT16 *p = (UINT16*)pSurface;
  602. for (DWORD x = dwWidth; x > 0; x--)
  603. {
  604. *p++ = (UINT16)dwColor;
  605. }
  606. pSurface += m_pColor->GetPitch();
  607. }
  608. }
  609. break;
  610. case RD_SF_B2G3R3:
  611. {
  612. for (DWORD y = dwHeight; y > 0; y--)
  613. {
  614. UINT8 *p = (UINT8*)pSurface;
  615. for (DWORD x = dwWidth; x > 0; x--)
  616. {
  617. *p++ = (UINT8)dwColor;
  618. }
  619. pSurface += m_pColor->GetPitch();
  620. }
  621. }
  622. break;
  623. default:
  624. {
  625. for (int y = y0; y < pData->Rects[i].bottom; ++y)
  626. {
  627. for (int x = x0; x < pData->Rects[i].right; ++x)
  628. {
  629. this->WritePixelColor(x, y, fillColor, TRUE);
  630. }
  631. }
  632. }
  633. }
  634. }
  635. }
  636. //-----------------------------------------------------------------------------
  637. //
  638. // Clear specified rectangles in the depth buffer
  639. // Directly handles the command from the DP2 stream
  640. //
  641. //-----------------------------------------------------------------------------
  642. void RDRenderTarget::ClearDepth(RDDepth fillDepth, LPD3DHAL_DP2COMMAND pCmd)
  643. {
  644. LPD3DHAL_DP2CLEAR pData = (LPD3DHAL_DP2CLEAR)(pCmd + 1);
  645. if (!m_pDepth) return;
  646. for (DWORD i = 0; i < pCmd->wStateCount; i++)
  647. {
  648. DWORD x0 = pData->Rects[i].left;
  649. DWORD y0 = pData->Rects[i].top;
  650. DWORD dwWidth = ( pData->Rects[i].right - x0 ) * m_pDepth->GetSamples();
  651. DWORD dwHeight = pData->Rects[i].bottom - y0;
  652. char* pSurface = PixelAddress( x0, y0, 0, 0, m_pDepth );
  653. switch ( m_pDepth->GetSurfaceFormat() )
  654. {
  655. case RD_SF_Z16S0:
  656. {
  657. UINT16 Depth = UINT16(fillDepth);
  658. for (DWORD y = dwHeight; y > 0; y--)
  659. {
  660. UINT16 *p = (UINT16*)pSurface;
  661. for (DWORD x = dwWidth; x > 0; x--)
  662. {
  663. *p++ = Depth;
  664. }
  665. pSurface += m_pDepth->GetPitch();
  666. }
  667. }
  668. break;
  669. case RD_SF_Z24S8:
  670. case RD_SF_Z24X8:
  671. case RD_SF_Z24X4S4:
  672. {
  673. UINT32 Depth = UINT32(fillDepth) << 8;
  674. for (DWORD y = dwHeight; y > 0; y--)
  675. {
  676. UINT32 *p = (UINT32*)pSurface;
  677. for (DWORD x = dwWidth; x > 0; x--)
  678. {
  679. // need to do read-modify-write to not step on stencil
  680. *p++ = (*p & ~(0xffffff00)) | Depth;
  681. }
  682. pSurface += m_pDepth->GetPitch();
  683. }
  684. }
  685. break;
  686. case RD_SF_S8Z24:
  687. case RD_SF_X8Z24:
  688. case RD_SF_X4S4Z24:
  689. {
  690. UINT32 Depth = UINT32(fillDepth) & 0x00ffffff;
  691. for (DWORD y = dwHeight; y > 0; y--)
  692. {
  693. UINT32 *p = (UINT32*)pSurface;
  694. for (DWORD x = dwWidth; x > 0; x--)
  695. {
  696. // need to do read-modify-write to not step on stencil
  697. *p++ = (*p & ~(0x00ffffff)) | Depth;
  698. }
  699. pSurface += m_pDepth->GetPitch();
  700. }
  701. }
  702. break;
  703. case RD_SF_Z15S1:
  704. {
  705. UINT16 Depth = UINT16(fillDepth) << 1;
  706. for (DWORD y = dwHeight; y > 0; y--)
  707. {
  708. UINT16 *p = (UINT16*)pSurface;
  709. for (DWORD x = dwWidth; x > 0; x--)
  710. {
  711. // need to do read-modify-write to not step on stencil
  712. *p++ = (*p & ~(0xfffe)) | Depth;
  713. }
  714. pSurface += m_pDepth->GetPitch();
  715. }
  716. }
  717. break;
  718. case RD_SF_S1Z15:
  719. {
  720. UINT16 Depth = UINT16(fillDepth) & 0x7fff;
  721. for (DWORD y = dwHeight; y > 0; y--)
  722. {
  723. UINT16 *p = (UINT16*)pSurface;
  724. for (DWORD x = dwWidth; x > 0; x--)
  725. {
  726. // need to do read-modify-write to not step on stencil
  727. *p++ = (*p & ~(0x7fff)) | Depth;
  728. }
  729. pSurface += m_pDepth->GetPitch();
  730. }
  731. }
  732. break;
  733. case RD_SF_Z32S0:
  734. {
  735. UINT32 Depth = UINT32(fillDepth);
  736. for (DWORD y = dwHeight; y > 0; y--)
  737. {
  738. UINT32 *p = (UINT32*)pSurface;
  739. for (DWORD x = dwWidth; x > 0; x--)
  740. {
  741. *p++ = Depth;
  742. }
  743. pSurface += m_pDepth->GetPitch();
  744. }
  745. }
  746. break;
  747. default:
  748. {
  749. for (int y = y0; y < pData->Rects[i].bottom; ++y)
  750. {
  751. for (int x = x0; x < pData->Rects[i].right; ++x)
  752. {
  753. this->WritePixelDepth(x, y, fillDepth);
  754. }
  755. }
  756. }
  757. }
  758. }
  759. }
  760. //-----------------------------------------------------------------------------
  761. //
  762. // Clear specified rectangles in the stencil buffer
  763. // Directly handles the command from the DP2 stream
  764. //
  765. //-----------------------------------------------------------------------------
  766. void RDRenderTarget::ClearStencil(UINT8 uStencil, LPD3DHAL_DP2COMMAND pCmd)
  767. {
  768. LPD3DHAL_DP2CLEAR pData = (LPD3DHAL_DP2CLEAR)(pCmd + 1);
  769. for (DWORD i = 0; i < pCmd->wStateCount; i++)
  770. {
  771. DWORD x0 = pData->Rects[i].left;
  772. DWORD y0 = pData->Rects[i].top;
  773. DWORD dwWidth = (pData->Rects[i].right - x0 ) * m_pDepth->GetSamples();
  774. DWORD dwHeight = pData->Rects[i].bottom - y0;
  775. char* pSurface = PixelAddress( x0, y0, 0, 0, m_pDepth );
  776. switch ( m_pDepth->GetSurfaceFormat() )
  777. {
  778. case RD_SF_Z24S8:
  779. {
  780. for (DWORD y = dwHeight; y > 0; y--)
  781. {
  782. UINT8 *p = (UINT8*)pSurface;
  783. for (DWORD x = dwWidth; x > 0; x--)
  784. {
  785. *p = uStencil;
  786. p += 4;
  787. }
  788. pSurface += m_pDepth->GetPitch();
  789. }
  790. }
  791. break;
  792. case RD_SF_S8Z24:
  793. {
  794. for (DWORD y = dwHeight; y > 0; y--)
  795. {
  796. UINT8 *p = (UINT8*)&pSurface[3];
  797. for (DWORD x = dwWidth; x > 0; x--)
  798. {
  799. *p = uStencil;
  800. p += 4;
  801. }
  802. pSurface += m_pDepth->GetPitch();
  803. }
  804. }
  805. break;
  806. case RD_SF_Z24X4S4:
  807. {
  808. UINT32 stencil = uStencil & 0xf;
  809. for (DWORD y = dwHeight; y > 0; y--)
  810. {
  811. UINT32 *p = (UINT32*)pSurface;
  812. for (DWORD x = dwWidth; x > 0; x--)
  813. {
  814. // need to do read-modify-write to not step on depth
  815. *p++ = (*p & ~(0x000000ff)) | stencil;
  816. }
  817. pSurface += m_pDepth->GetPitch();
  818. }
  819. }
  820. break;
  821. case RD_SF_X4S4Z24:
  822. {
  823. UINT32 stencil = (uStencil & 0xf) << 24;
  824. for (DWORD y = dwHeight; y > 0; y--)
  825. {
  826. UINT32 *p = (UINT32*)pSurface;
  827. for (DWORD x = dwWidth; x > 0; x--)
  828. {
  829. // need to do read-modify-write to not step on depth
  830. *p++ = (*p & ~(0xff000000)) | stencil;
  831. }
  832. pSurface += m_pDepth->GetPitch();
  833. }
  834. }
  835. break;
  836. case RD_SF_Z15S1:
  837. {
  838. UINT16 stencil = uStencil & 0x1;
  839. for (DWORD y = dwHeight; y > 0; y--)
  840. {
  841. UINT16 *p = (UINT16*)pSurface;
  842. for (DWORD x = dwWidth; x > 0; x--)
  843. {
  844. // need to do read-modify-write to not step on depth
  845. *p++ = (*p & ~(0x0001)) | stencil;
  846. }
  847. pSurface += m_pDepth->GetPitch();
  848. }
  849. }
  850. break;
  851. case RD_SF_S1Z15:
  852. {
  853. UINT16 stencil = uStencil << 15;
  854. for (DWORD y = dwHeight; y > 0; y--)
  855. {
  856. UINT16 *p = (UINT16*)pSurface;
  857. for (DWORD x = dwWidth; x > 0; x--)
  858. {
  859. // need to do read-modify-write to not step on depth
  860. *p++ = (*p & ~(0x8000)) | stencil;
  861. }
  862. pSurface += m_pDepth->GetPitch();
  863. }
  864. }
  865. break;
  866. case RD_SF_Z16S0:
  867. case RD_SF_Z32S0:
  868. break;
  869. default:
  870. {
  871. for (int y = y0; y < pData->Rects[i].bottom; ++y)
  872. {
  873. for (int x = x0; x < pData->Rects[i].right; ++x)
  874. {
  875. this->WritePixelStencil(x, y, uStencil);
  876. }
  877. }
  878. }
  879. }
  880. }
  881. }
  882. //-----------------------------------------------------------------------------
  883. //
  884. // Clear specified rectangles in the depth and stencil buffers
  885. // Directly handles the command from the DP2 stream
  886. //
  887. //-----------------------------------------------------------------------------
  888. void RDRenderTarget::ClearDepthStencil(RDDepth fillDepth, UINT8 uStencil, LPD3DHAL_DP2COMMAND pCmd)
  889. {
  890. LPD3DHAL_DP2CLEAR pData = (LPD3DHAL_DP2CLEAR)(pCmd + 1);
  891. for (DWORD i = 0; i < pCmd->wStateCount; i++)
  892. {
  893. DWORD x0 = pData->Rects[i].left;
  894. DWORD y0 = pData->Rects[i].top;
  895. DWORD dwWidth = ( pData->Rects[i].right - x0 ) * m_pDepth->GetSamples();
  896. DWORD dwHeight = pData->Rects[i].bottom - y0;
  897. char* pSurface = PixelAddress( x0, y0, 0, 0, m_pDepth );
  898. switch (m_pDepth->GetSurfaceFormat())
  899. {
  900. case RD_SF_Z16S0:
  901. case RD_SF_Z32S0:
  902. break;
  903. case RD_SF_Z24S8:
  904. case RD_SF_Z24X8:
  905. case RD_SF_S8Z24:
  906. case RD_SF_X8Z24:
  907. case RD_SF_Z24X4S4:
  908. case RD_SF_X4S4Z24:
  909. {
  910. UINT32 v;
  911. switch (m_pDepth->GetSurfaceFormat())
  912. {
  913. case RD_SF_Z24S8: v = (UINT32(fillDepth) << 8) + uStencil; break;
  914. case RD_SF_Z24X8: v = (UINT32(fillDepth) << 8); break;
  915. case RD_SF_S8Z24: v = (UINT32(fillDepth) & 0x00ffffff) + (uStencil << 24); break;
  916. case RD_SF_X8Z24: v = (UINT32(fillDepth) & 0x00ffffff); break;
  917. case RD_SF_Z24X4S4: v = (UINT32(fillDepth) << 8) + (uStencil & 0xf); break;
  918. case RD_SF_X4S4Z24: v = (UINT32(fillDepth) & 0x00ffffff) + ((uStencil & 0xf) << 24); break;
  919. }
  920. for (DWORD y = dwHeight; y > 0; y--)
  921. {
  922. UINT32 *p = (UINT32*)pSurface;
  923. for (DWORD x = dwWidth; x > 0; x--)
  924. {
  925. *p++ = v;
  926. }
  927. pSurface += m_pDepth->GetPitch();
  928. }
  929. }
  930. break;
  931. case RD_SF_Z15S1:
  932. case RD_SF_S1Z15:
  933. {
  934. UINT16 v;
  935. switch (m_pDepth->GetSurfaceFormat())
  936. {
  937. case RD_SF_Z15S1: v = (UINT16(fillDepth) << 1) + (uStencil & 0x1); break;
  938. case RD_SF_S1Z15: v = (UINT16(fillDepth) & 0x7fff) + (uStencil << 15); break;
  939. }
  940. for (DWORD y = dwHeight; y > 0; y--)
  941. {
  942. UINT16 *p = (UINT16*)pSurface;
  943. for (DWORD x = dwWidth; x > 0; x--)
  944. {
  945. *p++ = v;
  946. }
  947. pSurface += m_pDepth->GetPitch();
  948. }
  949. }
  950. break;
  951. default:
  952. {
  953. for (int y = y0; y < pData->Rects[i].bottom; ++y)
  954. {
  955. for (int x = x0; x < pData->Rects[i].right; ++x)
  956. {
  957. this->WritePixelDepth(x, y, fillDepth);
  958. this->WritePixelStencil(x, y, uStencil);
  959. }
  960. }
  961. }
  962. }
  963. }
  964. }
  965. ///////////////////////////////////////////////////////////////////////////////
  966. // end