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.

885 lines
29 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 1998.
  3. //
  4. // refrast.cpp
  5. //
  6. // Direct3D Reference Rasterizer - public interface
  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 S3 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. ReferenceRasterizer::SetRenderTarget( RRRenderTarget* 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. // free fragment buffer array - will reallocate with new size when needed
  62. if (pRenderTarget->m_iWidth != m_iFragBufWidth ||
  63. pRenderTarget->m_iHeight != m_iFragBufHeight)
  64. {
  65. MEMFREE( m_ppFragBuf ); m_ppFragBuf = NULL;
  66. m_iFragBufWidth = pRenderTarget->m_iWidth;
  67. m_iFragBufHeight = pRenderTarget->m_iHeight;
  68. }
  69. }
  70. //-----------------------------------------------------------------------------
  71. //
  72. // SetTextureStageState -
  73. //
  74. //-----------------------------------------------------------------------------
  75. void
  76. ReferenceRasterizer::SetTextureStageState(
  77. DWORD dwStage, DWORD dwStageState, DWORD dwValue )
  78. {
  79. // check for range before continuing
  80. if ( dwStage >= D3DHAL_TSS_MAXSTAGES )
  81. {
  82. return;
  83. }
  84. if ( dwStageState > D3DTSS_MAX )
  85. {
  86. return;
  87. }
  88. // set in internal per-stage state
  89. m_TextureStageState[dwStage].m_dwVal[dwStageState] = dwValue;
  90. switch ( dwStageState )
  91. {
  92. case D3DTSS_TEXTUREMAP:
  93. // bind texture indicated by handle to m_pTexture array
  94. if (IsDriverDX6AndBefore() || IsInterfaceDX6AndBefore())
  95. {
  96. // This is the legacy behavior (prev. to DX7)
  97. MapTextureHandleToDevice( dwStage );
  98. }
  99. else
  100. {
  101. // This is the new behavior (DX7 and beyond)
  102. SetTextureHandle( dwStage, dwValue );
  103. }
  104. break;
  105. case D3DTSS_COLOROP:
  106. // may need to recompute count of active textures based on COLOROP change
  107. UpdateActiveTexStageCount();
  108. break;
  109. case D3DTSS_ADDRESS:
  110. // map single set ADDRESS to both U and V controls
  111. m_TextureStageState[dwStage].m_dwVal[D3DTSS_ADDRESSU] = dwValue;
  112. m_TextureStageState[dwStage].m_dwVal[D3DTSS_ADDRESSV] = dwValue;
  113. }
  114. }
  115. //-----------------------------------------------------------------------------
  116. //
  117. // TextureCreate - Instantiates new RRTexture object, computes texture handle
  118. // to associate with it, and returns both to caller. Note that texture handle
  119. // is a pointer and can be used to get at the corresponding texture object.
  120. //
  121. // TODO: this is not 64 bit clean
  122. //
  123. //-----------------------------------------------------------------------------
  124. BOOL
  125. ReferenceRasterizer::TextureCreate(
  126. LPD3DTEXTUREHANDLE phTex, RRTexture** ppTex )
  127. {
  128. // allocate internal texture structure
  129. *ppTex = new RRTexture( );
  130. _ASSERTa( NULL != *ppTex, "new failure on texture create", return FALSE; );
  131. // use separately allocated pointer for handle
  132. RRTexture** ppTexForHandle = (RRTexture**)MEMALLOC( sizeof(RRTexture*) );
  133. _ASSERTa( NULL != ppTexForHandle, "malloc failure on texture create", return FALSE; );
  134. *ppTexForHandle = *ppTex;
  135. // return texture handle
  136. (*ppTex)->m_hTex = (ULONG_PTR)ppTexForHandle;
  137. *phTex = (*ppTex)->m_hTex;
  138. return TRUE;
  139. }
  140. //-----------------------------------------------------------------------------
  141. //
  142. // TextureCreate -
  143. //
  144. //-----------------------------------------------------------------------------
  145. BOOL
  146. ReferenceRasterizer::TextureCreate(
  147. DWORD dwHandle, RRTexture** ppTex )
  148. {
  149. // allocate internal texture structure
  150. *ppTex = new RRTexture( );
  151. _ASSERTa( NULL != *ppTex, "new failure on texture create", return FALSE; );
  152. // assign texture handle
  153. (*ppTex)->m_hTex = dwHandle;
  154. return TRUE;
  155. }
  156. //-----------------------------------------------------------------------------
  157. //
  158. // TextureDestroy -
  159. //
  160. //-----------------------------------------------------------------------------
  161. BOOL
  162. ReferenceRasterizer::TextureDestroy( D3DTEXTUREHANDLE hTex )
  163. {
  164. // first check if texture about to be destroyed is mapped - if so then
  165. // unmap it
  166. for ( int iStage=0; iStage<D3DHAL_TSS_MAXSTAGES; iStage++ )
  167. {
  168. if ( hTex == m_TextureStageState[iStage].m_dwVal[D3DTSS_TEXTUREMAP] )
  169. {
  170. SetTextureStageState( iStage, D3DTSS_TEXTUREMAP, 0x0 );
  171. }
  172. }
  173. // resolve handle to RRTexture pointer
  174. RRTexture* pTex = MapHandleToTexture( hTex );
  175. if ( NULL == pTex ) { return FALSE; }
  176. // free the handle pointer
  177. RRTexture** ppTex = (RRTexture**)ULongToPtr(hTex);
  178. if ( NULL != ppTex) { MEMFREE( ppTex ); }
  179. // free the RRTexture
  180. delete pTex;
  181. return TRUE;
  182. }
  183. //-----------------------------------------------------------------------------
  184. //
  185. // TextureGetSurf -
  186. //
  187. //-----------------------------------------------------------------------------
  188. DWORD
  189. ReferenceRasterizer::TextureGetSurf( D3DTEXTUREHANDLE hTex )
  190. {
  191. RRTexture* pTex = MapHandleToTexture(hTex);
  192. if ( NULL == pTex ) { return 0x0; }
  193. return (ULONG_PTR)( pTex->m_pDDSLcl[0] );
  194. }
  195. //-----------------------------------------------------------------------------
  196. //
  197. // GetCurrentTextureMaps - This function fills in a passed array texture handles
  198. // and pointers. The array should be sized by D3DHAL_TSS_MAXSTAGES.
  199. //
  200. // This is used to facilitate external locking/unlocking of surfaces used for
  201. // textures.
  202. //
  203. //-----------------------------------------------------------------------------
  204. int
  205. ReferenceRasterizer::GetCurrentTextureMaps(
  206. D3DTEXTUREHANDLE *phTex, RRTexture** pTex)
  207. {
  208. UpdateActiveTexStageCount();
  209. for ( int i=0; i<m_cActiveTextureStages; i++ )
  210. {
  211. if ( NULL == m_pTexture[i] )
  212. {
  213. phTex[i] = 0x0;
  214. pTex[i] = NULL;
  215. }
  216. else
  217. {
  218. phTex[i] = m_pTexture[i]->m_hTex;
  219. pTex[i] = m_pTexture[i];
  220. }
  221. }
  222. return m_cActiveTextureStages;
  223. }
  224. //-----------------------------------------------------------------------------
  225. //
  226. // SceneCapture - Used to trigger fragment buffer resolve.
  227. //
  228. //-----------------------------------------------------------------------------
  229. void
  230. ReferenceRasterizer::SceneCapture( DWORD dwFlags )
  231. {
  232. switch (dwFlags)
  233. {
  234. case D3DHAL_SCENE_CAPTURE_START:
  235. break;
  236. case D3DHAL_SCENE_CAPTURE_END:
  237. DoBufferResolve();
  238. break;
  239. }
  240. }
  241. //-----------------------------------------------------------------------------
  242. //
  243. // Query functions to get pointer to current render target and render state.
  244. //
  245. //-----------------------------------------------------------------------------
  246. RRRenderTarget*
  247. ReferenceRasterizer::GetRenderTarget(void)
  248. {
  249. return m_pRenderTarget;
  250. }
  251. //-----------------------------------------------------------------------------
  252. DWORD*
  253. ReferenceRasterizer::GetRenderState(void)
  254. {
  255. return &(m_dwRenderState[0]);
  256. }
  257. //-----------------------------------------------------------------------------
  258. DWORD*
  259. ReferenceRasterizer::GetTextureStageState(DWORD dwStage)
  260. {
  261. return &(m_TextureStageState[dwStage].m_dwVal[0]);
  262. }
  263. //-----------------------------------------------------------------------------
  264. //
  265. // Begin/End bracket functions - Called before/after a list of primitives are
  266. // rendered.
  267. //
  268. //-----------------------------------------------------------------------------
  269. HRESULT
  270. ReferenceRasterizer::BeginRendering( DWORD dwFVFControl )
  271. {
  272. // set FVF control word - this specifies the vertex types for this
  273. // begin/end sequence
  274. if ( dwFVFControl )
  275. {
  276. m_qwFVFControl = dwFVFControl;
  277. }
  278. else
  279. {
  280. // Legacy TLVERTEX's
  281. m_qwFVFControl = D3DFVF_TLVERTEX;
  282. }
  283. // set colorkey enable
  284. for (INT32 i = 0; i < m_cActiveTextureStages; i++)
  285. {
  286. if ( m_pTexture[i] != NULL )
  287. {
  288. m_pTexture[i]->m_bDoColorKeyKill = FALSE;
  289. m_pTexture[i]->m_bDoColorKeyZero = FALSE;
  290. if ( m_pTexture[i]->m_uFlags & RR_TEXTURE_HAS_CK)
  291. {
  292. if ( m_dwRenderState[D3DRENDERSTATE_COLORKEYBLENDENABLE] )
  293. {
  294. m_pTexture[i]->m_bDoColorKeyZero = TRUE;
  295. }
  296. else
  297. {
  298. if ( m_dwRenderState[D3DRENDERSTATE_COLORKEYENABLE] )
  299. {
  300. m_pTexture[i]->m_bDoColorKeyKill = TRUE;
  301. }
  302. }
  303. }
  304. }
  305. }
  306. #ifdef _X86_
  307. // save floating point mode and set to extended precision mode
  308. {
  309. WORD wTemp, wSave;
  310. __asm
  311. {
  312. fstcw wSave
  313. mov ax, wSave
  314. or ax, 300h ;; extended precision mode
  315. mov wTemp, ax
  316. fldcw wTemp
  317. }
  318. m_wSaveFP = wSave;
  319. }
  320. #endif
  321. m_bInBegin = TRUE;
  322. return S_OK;
  323. }
  324. //-----------------------------------------------------------------------------
  325. HRESULT
  326. ReferenceRasterizer::EndRendering( void )
  327. {
  328. if ( m_bInBegin )
  329. {
  330. #ifdef _X86_
  331. // restore floating point mode
  332. {
  333. WORD wSave = m_wSaveFP;
  334. __asm {fldcw wSave}
  335. }
  336. #endif
  337. m_bInBegin = FALSE;
  338. }
  339. return S_OK;
  340. }
  341. //-----------------------------------------------------------------------------
  342. //
  343. // Clear specified rectangles in the render target
  344. // Directly handles the command from the DP2 stream
  345. //
  346. //-----------------------------------------------------------------------------
  347. HRESULT ReferenceRasterizer::Clear(LPD3DHAL_DP2COMMAND pCmd)
  348. {
  349. LPD3DHAL_DP2CLEAR pData = (LPD3DHAL_DP2CLEAR)(pCmd + 1);
  350. WORD i;
  351. INT32 x,y;
  352. RRColor fillColor(pData->dwFillColor);
  353. RRDepth fillDepth(m_pRenderTarget->m_DepthSType);
  354. fillDepth = pData->dvFillDepth;
  355. #ifdef _X86_
  356. // Float to integer conversion routines for 24+ bit buffers work
  357. // only with extended FPU mode.
  358. //
  359. WORD wSaveFP;
  360. // save floating point mode and set to extended precision mode
  361. {
  362. WORD wTemp, wSave;
  363. __asm
  364. {
  365. fstcw wSaveFP
  366. mov ax, wSaveFP
  367. or ax, 300h ;; extended precision mode
  368. mov wTemp, ax
  369. fldcw wTemp
  370. }
  371. }
  372. #endif
  373. if(pData->dwFlags & D3DCLEAR_TARGET)
  374. {
  375. if (m_dwRenderState[D3DRENDERSTATE_DITHERENABLE] == FALSE)
  376. {
  377. m_pRenderTarget->Clear(fillColor, pCmd);
  378. }
  379. else
  380. {
  381. for (i = 0; i < pCmd->wStateCount; i++)
  382. {
  383. for (y = pData->Rects[i].top; y < pData->Rects[i].bottom; ++y)
  384. {
  385. for (x = pData->Rects[i].left; x < pData->Rects[i].right; ++x)
  386. {
  387. m_pRenderTarget->WritePixelColor(x, y, fillColor, TRUE);
  388. }
  389. }
  390. }
  391. }
  392. }
  393. switch (pData->dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL))
  394. {
  395. case (D3DCLEAR_ZBUFFER):
  396. m_pRenderTarget->ClearDepth(fillDepth, pCmd);
  397. break;
  398. case (D3DCLEAR_STENCIL):
  399. m_pRenderTarget->ClearStencil(pData->dwFillStencil, pCmd);
  400. break;
  401. case (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL):
  402. m_pRenderTarget->ClearDepthStencil(fillDepth, pData->dwFillStencil, pCmd);
  403. break;
  404. }
  405. #ifdef _X86_
  406. // restore floating point mode
  407. {
  408. __asm {fldcw wSaveFP}
  409. }
  410. #endif
  411. return D3D_OK;
  412. }
  413. //-----------------------------------------------------------------------------
  414. //
  415. // Clear specified rectangles in the render target
  416. // Directly handles the command from the DP2 stream
  417. //
  418. //-----------------------------------------------------------------------------
  419. void RRRenderTarget::Clear(RRColor fillColor, LPD3DHAL_DP2COMMAND pCmd)
  420. {
  421. LPD3DHAL_DP2CLEAR pData = (LPD3DHAL_DP2CLEAR)(pCmd + 1);
  422. UINT32 dwColor = 0;
  423. fillColor.ConvertTo( m_ColorSType, 0.5f, (char*)&dwColor);
  424. for (DWORD i = 0; i < pCmd->wStateCount; i++)
  425. {
  426. DWORD x0 = pData->Rects[i].left;
  427. DWORD y0 = pData->Rects[i].top;
  428. DWORD dwWidth = pData->Rects[i].right - x0;
  429. DWORD dwHeight = pData->Rects[i].bottom - y0;
  430. char* pSurface = PixelAddress( x0, y0, m_pColorBufBits, m_iColorBufPitch, m_ColorSType );
  431. switch ( m_ColorSType )
  432. {
  433. case RR_STYPE_B8G8R8A8:
  434. case RR_STYPE_B8G8R8X8:
  435. {
  436. for (DWORD y = dwHeight; y > 0; y--)
  437. {
  438. UINT32 *p = (UINT32*)pSurface;
  439. for (DWORD x = dwWidth; x > 0; x--)
  440. {
  441. *p++ = dwColor;
  442. }
  443. pSurface += m_iColorBufPitch;
  444. }
  445. }
  446. break;
  447. case RR_STYPE_B8G8R8:
  448. {
  449. for (DWORD y = dwHeight; y > 0; y--)
  450. {
  451. UINT8 *p = (UINT8*)pSurface;
  452. for (DWORD x = dwWidth; x > 0; x--)
  453. {
  454. *p++ = ((UINT8*)&dwColor)[0];
  455. *p++ = ((UINT8*)&dwColor)[1];
  456. *p++ = ((UINT8*)&dwColor)[2];
  457. }
  458. pSurface += m_iColorBufPitch;
  459. }
  460. }
  461. break;
  462. case RR_STYPE_B4G4R4A4:
  463. case RR_STYPE_B5G6R5:
  464. case RR_STYPE_B5G5R5A1:
  465. case RR_STYPE_B5G5R5:
  466. {
  467. for (DWORD y = dwHeight; y > 0; y--)
  468. {
  469. UINT16 *p = (UINT16*)pSurface;
  470. for (DWORD x = dwWidth; x > 0; x--)
  471. {
  472. *p++ = (UINT16)dwColor;
  473. }
  474. pSurface += m_iColorBufPitch;
  475. }
  476. }
  477. break;
  478. case RR_STYPE_B2G3R3:
  479. {
  480. for (DWORD y = dwHeight; y > 0; y--)
  481. {
  482. UINT8 *p = (UINT8*)pSurface;
  483. for (DWORD x = dwWidth; x > 0; x--)
  484. {
  485. *p++ = (UINT8)dwColor;
  486. }
  487. pSurface += m_iColorBufPitch;
  488. }
  489. }
  490. break;
  491. default:
  492. {
  493. for (int y = y0; y < pData->Rects[i].bottom; ++y)
  494. {
  495. for (int x = x0; x < pData->Rects[i].right; ++x)
  496. {
  497. this->WritePixelColor(x, y, fillColor, TRUE);
  498. }
  499. }
  500. }
  501. }
  502. }
  503. }
  504. //-----------------------------------------------------------------------------
  505. //
  506. // Clear specified rectangles in the depth buffer
  507. // Directly handles the command from the DP2 stream
  508. //
  509. //-----------------------------------------------------------------------------
  510. void RRRenderTarget::ClearDepth(RRDepth fillDepth, LPD3DHAL_DP2COMMAND pCmd)
  511. {
  512. LPD3DHAL_DP2CLEAR pData = (LPD3DHAL_DP2CLEAR)(pCmd + 1);
  513. for (DWORD i = 0; i < pCmd->wStateCount; i++)
  514. {
  515. DWORD x0 = pData->Rects[i].left;
  516. DWORD y0 = pData->Rects[i].top;
  517. DWORD dwWidth = pData->Rects[i].right - x0;
  518. DWORD dwHeight = pData->Rects[i].bottom - y0;
  519. char* pSurface = PixelAddress( x0, y0, m_pDepthBufBits, m_iDepthBufPitch, m_DepthSType);
  520. switch (m_DepthSType)
  521. {
  522. case RR_STYPE_Z16S0:
  523. {
  524. UINT16 Depth = UINT16(fillDepth);
  525. for (DWORD y = dwHeight; y > 0; y--)
  526. {
  527. UINT16 *p = (UINT16*)pSurface;
  528. for (DWORD x = dwWidth; x > 0; x--)
  529. {
  530. *p++ = Depth;
  531. }
  532. pSurface += m_iDepthBufPitch;
  533. }
  534. }
  535. break;
  536. case RR_STYPE_Z24S8:
  537. case RR_STYPE_Z24S4:
  538. {
  539. UINT32 Depth = UINT32(fillDepth) << 8;
  540. for (DWORD y = dwHeight; y > 0; y--)
  541. {
  542. UINT32 *p = (UINT32*)pSurface;
  543. for (DWORD x = dwWidth; x > 0; x--)
  544. {
  545. // need to do read-modify-write to not step on stencil
  546. *p++ = (*p & ~(0xffffff00)) | Depth;
  547. }
  548. pSurface += m_iDepthBufPitch;
  549. }
  550. }
  551. break;
  552. case RR_STYPE_S8Z24:
  553. case RR_STYPE_S4Z24:
  554. {
  555. UINT32 Depth = UINT32(fillDepth) & 0x00ffffff;
  556. for (DWORD y = dwHeight; y > 0; y--)
  557. {
  558. UINT32 *p = (UINT32*)pSurface;
  559. for (DWORD x = dwWidth; x > 0; x--)
  560. {
  561. // need to do read-modify-write to not step on stencil
  562. *p++ = (*p & ~(0x00ffffff)) | Depth;
  563. }
  564. pSurface += m_iDepthBufPitch;
  565. }
  566. }
  567. break;
  568. case RR_STYPE_Z15S1:
  569. {
  570. UINT16 Depth = UINT16(fillDepth) << 1;
  571. for (DWORD y = dwHeight; y > 0; y--)
  572. {
  573. UINT16 *p = (UINT16*)pSurface;
  574. for (DWORD x = dwWidth; x > 0; x--)
  575. {
  576. // need to do read-modify-write to not step on stencil
  577. *p++ = (*p & ~(0xfffe)) | Depth;
  578. }
  579. pSurface += m_iDepthBufPitch;
  580. }
  581. }
  582. break;
  583. case RR_STYPE_S1Z15:
  584. {
  585. UINT16 Depth = UINT16(fillDepth) & 0x7fff;
  586. for (DWORD y = dwHeight; y > 0; y--)
  587. {
  588. UINT16 *p = (UINT16*)pSurface;
  589. for (DWORD x = dwWidth; x > 0; x--)
  590. {
  591. // need to do read-modify-write to not step on stencil
  592. *p++ = (*p & ~(0x7fff)) | Depth;
  593. }
  594. pSurface += m_iDepthBufPitch;
  595. }
  596. }
  597. break;
  598. case RR_STYPE_Z32S0:
  599. {
  600. UINT32 Depth = UINT32(fillDepth);
  601. for (DWORD y = dwHeight; y > 0; y--)
  602. {
  603. UINT32 *p = (UINT32*)pSurface;
  604. for (DWORD x = dwWidth; x > 0; x--)
  605. {
  606. *p++ = Depth;
  607. }
  608. pSurface += m_iDepthBufPitch;
  609. }
  610. }
  611. break;
  612. default:
  613. {
  614. for (int y = y0; y < pData->Rects[i].bottom; ++y)
  615. {
  616. for (int x = x0; x < pData->Rects[i].right; ++x)
  617. {
  618. this->WritePixelDepth(x, y, fillDepth);
  619. }
  620. }
  621. }
  622. }
  623. }
  624. }
  625. //-----------------------------------------------------------------------------
  626. //
  627. // Clear specified rectangles in the stencil buffer
  628. // Directly handles the command from the DP2 stream
  629. //
  630. //-----------------------------------------------------------------------------
  631. void RRRenderTarget::ClearStencil(UINT8 uStencil, LPD3DHAL_DP2COMMAND pCmd)
  632. {
  633. LPD3DHAL_DP2CLEAR pData = (LPD3DHAL_DP2CLEAR)(pCmd + 1);
  634. for (DWORD i = 0; i < pCmd->wStateCount; i++)
  635. {
  636. DWORD x0 = pData->Rects[i].left;
  637. DWORD y0 = pData->Rects[i].top;
  638. DWORD dwWidth = pData->Rects[i].right - x0;
  639. DWORD dwHeight = pData->Rects[i].bottom - y0;
  640. char* pSurface = PixelAddress( x0, y0, m_pDepthBufBits, m_iDepthBufPitch, m_DepthSType);
  641. switch (m_DepthSType)
  642. {
  643. case RR_STYPE_Z24S8:
  644. {
  645. for (DWORD y = dwHeight; y > 0; y--)
  646. {
  647. UINT8 *p = (UINT8*)pSurface;
  648. for (DWORD x = dwWidth; x > 0; x--)
  649. {
  650. *p = uStencil;
  651. p += 4;
  652. }
  653. pSurface += m_iDepthBufPitch;
  654. }
  655. }
  656. break;
  657. case RR_STYPE_S8Z24:
  658. {
  659. for (DWORD y = dwHeight; y > 0; y--)
  660. {
  661. UINT8 *p = (UINT8*)&pSurface[3];
  662. for (DWORD x = dwWidth; x > 0; x--)
  663. {
  664. *p = uStencil;
  665. p += 4;
  666. }
  667. pSurface += m_iDepthBufPitch;
  668. }
  669. }
  670. break;
  671. case RR_STYPE_Z24S4:
  672. {
  673. UINT32 stencil = uStencil & 0xf;
  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 depth
  680. *p++ = (*p & ~(0x000000ff)) | stencil;
  681. }
  682. pSurface += m_iDepthBufPitch;
  683. }
  684. }
  685. break;
  686. case RR_STYPE_S4Z24:
  687. {
  688. UINT32 stencil = (uStencil & 0xf) << 24;
  689. for (DWORD y = dwHeight; y > 0; y--)
  690. {
  691. UINT32 *p = (UINT32*)pSurface;
  692. for (DWORD x = dwWidth; x > 0; x--)
  693. {
  694. // need to do read-modify-write to not step on depth
  695. *p++ = (*p & ~(0xff000000)) | stencil;
  696. }
  697. pSurface += m_iDepthBufPitch;
  698. }
  699. }
  700. break;
  701. case RR_STYPE_Z15S1:
  702. {
  703. UINT16 stencil = uStencil & 0x1;
  704. for (DWORD y = dwHeight; y > 0; y--)
  705. {
  706. UINT16 *p = (UINT16*)pSurface;
  707. for (DWORD x = dwWidth; x > 0; x--)
  708. {
  709. // need to do read-modify-write to not step on depth
  710. *p++ = (*p & ~(0x0001)) | stencil;
  711. }
  712. pSurface += m_iDepthBufPitch;
  713. }
  714. }
  715. break;
  716. case RR_STYPE_S1Z15:
  717. {
  718. UINT16 stencil = uStencil << 15;
  719. for (DWORD y = dwHeight; y > 0; y--)
  720. {
  721. UINT16 *p = (UINT16*)pSurface;
  722. for (DWORD x = dwWidth; x > 0; x--)
  723. {
  724. // need to do read-modify-write to not step on depth
  725. *p++ = (*p & ~(0x8000)) | stencil;
  726. }
  727. pSurface += m_iDepthBufPitch;
  728. }
  729. }
  730. break;
  731. case RR_STYPE_Z16S0:
  732. case RR_STYPE_Z32S0:
  733. break;
  734. default:
  735. {
  736. for (int y = y0; y < pData->Rects[i].bottom; ++y)
  737. {
  738. for (int x = x0; x < pData->Rects[i].right; ++x)
  739. {
  740. this->WritePixelStencil(x, y, uStencil);
  741. }
  742. }
  743. }
  744. }
  745. }
  746. }
  747. //-----------------------------------------------------------------------------
  748. //
  749. // Clear specified rectangles in the depth and stencil buffers
  750. // Directly handles the command from the DP2 stream
  751. //
  752. //-----------------------------------------------------------------------------
  753. void RRRenderTarget::ClearDepthStencil(RRDepth fillDepth, UINT8 uStencil, LPD3DHAL_DP2COMMAND pCmd)
  754. {
  755. LPD3DHAL_DP2CLEAR pData = (LPD3DHAL_DP2CLEAR)(pCmd + 1);
  756. for (DWORD i = 0; i < pCmd->wStateCount; i++)
  757. {
  758. DWORD x0 = pData->Rects[i].left;
  759. DWORD y0 = pData->Rects[i].top;
  760. DWORD dwWidth = pData->Rects[i].right - x0;
  761. DWORD dwHeight = pData->Rects[i].bottom - y0;
  762. char* pSurface = PixelAddress( x0, y0, m_pDepthBufBits, m_iDepthBufPitch, m_DepthSType);
  763. switch (m_DepthSType)
  764. {
  765. case RR_STYPE_Z16S0:
  766. case RR_STYPE_Z32S0:
  767. break;
  768. case RR_STYPE_Z24S8:
  769. case RR_STYPE_S8Z24:
  770. case RR_STYPE_Z24S4:
  771. case RR_STYPE_S4Z24:
  772. {
  773. UINT32 v;
  774. switch (m_DepthSType)
  775. {
  776. case RR_STYPE_Z24S8: v = (UINT32(fillDepth) << 8) + uStencil; break;
  777. case RR_STYPE_S8Z24: v = (UINT32(fillDepth) & 0x00ffffff) + (uStencil << 24); break;
  778. case RR_STYPE_Z24S4: v = (UINT32(fillDepth) << 8) + (uStencil & 0xf); break;
  779. case RR_STYPE_S4Z24: v = (UINT32(fillDepth) & 0x00ffffff) + ((uStencil & 0xf) << 24); break;
  780. }
  781. for (DWORD y = dwHeight; y > 0; y--)
  782. {
  783. UINT32 *p = (UINT32*)pSurface;
  784. for (DWORD x = dwWidth; x > 0; x--)
  785. {
  786. *p++ = v;
  787. }
  788. pSurface += m_iDepthBufPitch;
  789. }
  790. }
  791. break;
  792. case RR_STYPE_Z15S1:
  793. case RR_STYPE_S1Z15:
  794. {
  795. UINT16 v;
  796. switch (m_DepthSType)
  797. {
  798. case RR_STYPE_Z15S1: v = (UINT16(fillDepth) << 1) + (uStencil & 0x1); break;
  799. case RR_STYPE_S1Z15: v = (UINT16(fillDepth) & 0x7fff) + (uStencil << 15); break;
  800. }
  801. for (DWORD y = dwHeight; y > 0; y--)
  802. {
  803. UINT16 *p = (UINT16*)pSurface;
  804. for (DWORD x = dwWidth; x > 0; x--)
  805. {
  806. *p++ = v;
  807. }
  808. pSurface += m_iDepthBufPitch;
  809. }
  810. }
  811. break;
  812. default:
  813. {
  814. for (int y = y0; y < pData->Rects[i].bottom; ++y)
  815. {
  816. for (int x = x0; x < pData->Rects[i].right; ++x)
  817. {
  818. this->WritePixelDepth(x, y, fillDepth);
  819. this->WritePixelStencil(x, y, uStencil);
  820. }
  821. }
  822. }
  823. }
  824. }
  825. }
  826. ///////////////////////////////////////////////////////////////////////////////
  827. // end