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.

3213 lines
122 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * D3D SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: d3ddp2op.c
  8. *
  9. * Content: D3D DrawPrimitives2 command buffer operations support
  10. *
  11. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "glint.h"
  15. #include "dma.h"
  16. #include "tag.h"
  17. //-----------------------------------------------------------------------------
  18. //
  19. // __OP_IntersectRectl
  20. //
  21. // This function intersects two RECTLs. If no intersection exists returns FALSE
  22. //
  23. //-----------------------------------------------------------------------------
  24. BOOL
  25. __OP_IntersectRectl(
  26. RECTL* prcresult,
  27. RECTL* prcin1,
  28. RECT* prcin2)
  29. {
  30. prcresult->left = max(prcin1->left, prcin2->left);
  31. prcresult->right = min(prcin1->right, prcin2->right);
  32. if (prcresult->left < prcresult->right)
  33. {
  34. prcresult->top = max(prcin1->top, prcin2->top);
  35. prcresult->bottom = min(prcin1->bottom, prcin2->bottom);
  36. if (prcresult->top < prcresult->bottom)
  37. {
  38. return TRUE;
  39. }
  40. }
  41. return FALSE;
  42. } // __OP_IntersectRectl
  43. #if DX7_TEXMANAGEMENT
  44. VOID __OP_MarkManagedSurfDirty(P3_D3DCONTEXT* pContext,
  45. DWORD dwSurfHandle,
  46. P3_SURF_INTERNAL* pTexture);
  47. #endif
  48. //-----------------------------------------------------------------------------
  49. //
  50. // _D3D_OP_Clear2
  51. //
  52. // This function processes the D3DDP2OP_CLEAR DP2 command token.
  53. //
  54. // It builds a mask and a value for the stencil/depth clears. The mask is used
  55. // to stop unwanted bits being updated during the clear. The value is scaled in
  56. // the case of the Z depth, and is shifted in the case of the stencil. This
  57. // results in the correct value being written, at the correct location in the
  58. // ZBuffer, while doing fast-block fills through SGRAM
  59. //-----------------------------------------------------------------------------
  60. #define P3RX_UPDATE_WRITE_MASK(a) \
  61. if (dwCurrentMask != a) \
  62. { \
  63. P3_DMA_GET_BUFFER_ENTRIES(2); \
  64. SEND_P3_DATA(FBHardwareWriteMask, a); \
  65. P3_DMA_COMMIT_BUFFER(); \
  66. dwCurrentMask = a; \
  67. }
  68. VOID
  69. _D3D_OP_Clear2(
  70. P3_D3DCONTEXT* pContext,
  71. D3DHAL_DP2CLEAR* lpcd2,
  72. DWORD dwNumRects)
  73. {
  74. DWORD i;
  75. RECTL rect, rect_vwport;
  76. DWORD dwDepthValue;
  77. DWORD dwStencilValue;
  78. DWORD dwStencilMask;
  79. DWORD dwDepthMask;
  80. DWORD color;
  81. DWORD dwCurrentMask = 0xFFFFFFFF;
  82. BOOL bNoBlockFillZ = FALSE;
  83. BOOL bNoBlockFillStencil = FALSE;
  84. BOOL bComputeIntersections = FALSE;
  85. BYTE Bytes[4];
  86. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  87. HRESULT ddrval;
  88. D3DHAL_DP2CLEAR WholeViewport;
  89. P3_DMA_DEFS();
  90. DBG_CB_ENTRY(_D3D_OP_Clear2);
  91. // Check if we were asked to clear a valid buffer
  92. if ( (lpcd2->dwFlags & (D3DCLEAR_TARGET |
  93. D3DCLEAR_ZBUFFER |
  94. D3DCLEAR_STENCIL) ) == 0)
  95. {
  96. // We have been asked to do nothing - and that's what we've done.
  97. DBG_CB_EXIT(_D3D_OP_Clear2, DD_OK);
  98. return;
  99. }
  100. #if DX8_DDI
  101. // When zero clear rects is passed to a DX8 driver with D3DDP2OP_CLEAR
  102. // token, the driver should clear the whole viewport. The zero number
  103. // of rects could be passed only if D3D is using a pure device.
  104. // D3DCLEAR_COMPUTERECTS has been added to the dwFlags of D3DHAL_CLEARDATA.
  105. // When set, the flag means that user provided clear rects should be
  106. // culled against the current viewport.
  107. if (!(lpcd2->dwFlags & D3DCLEAR_COMPUTERECTS))
  108. {
  109. // Do nothing for non-pure device
  110. }
  111. else
  112. if (dwNumRects == 0)
  113. {
  114. // When wStateCount is zero we need to clear whole viewport
  115. WholeViewport.dwFlags = lpcd2->dwFlags;
  116. WholeViewport.dwFillColor = lpcd2->dwFillColor;
  117. WholeViewport.dvFillDepth = lpcd2->dvFillDepth;
  118. WholeViewport.dwFillStencil = lpcd2->dwFillStencil;
  119. WholeViewport.Rects[0].left = pContext->ViewportInfo.dwX;
  120. WholeViewport.Rects[0].top = pContext->ViewportInfo.dwY;
  121. WholeViewport.Rects[0].right = pContext->ViewportInfo.dwX +
  122. pContext->ViewportInfo.dwWidth;
  123. WholeViewport.Rects[0].bottom = pContext->ViewportInfo.dwY +
  124. pContext->ViewportInfo.dwHeight;
  125. // Replace pointers and continue as usual
  126. lpcd2 = &WholeViewport;
  127. dwNumRects = 1;
  128. }
  129. else
  130. {
  131. // We need to cull all rects against the current viewport
  132. // but in order not to allocate a temporary RECT array in
  133. // kernel heap we'll compute this inside the clearing loop
  134. rect_vwport.left = pContext->ViewportInfo.dwX;
  135. rect_vwport.top = pContext->ViewportInfo.dwY;
  136. rect_vwport.right = pContext->ViewportInfo.dwX +
  137. pContext->ViewportInfo.dwWidth;
  138. rect_vwport.bottom = pContext->ViewportInfo.dwY +
  139. pContext->ViewportInfo.dwHeight;
  140. bComputeIntersections = TRUE;
  141. }
  142. #endif // DX8_DDI
  143. // Check if there is any rect to clear at all
  144. if ( dwNumRects == 0)
  145. {
  146. // We have been asked to do nothing - and that's what we've done.
  147. DBG_CB_EXIT(_D3D_OP_Clear2, DD_OK);
  148. return;
  149. }
  150. // Wait until we have we finished flipping before clearing anything
  151. do
  152. {
  153. ddrval =
  154. _DX_QueryFlipStatus(pContext->pThisDisplay,
  155. pContext->pSurfRenderInt->fpVidMem,
  156. TRUE);
  157. } while ( FAILED (ddrval) );
  158. // Switch to hw Ddraw context in order to do the clears
  159. DDRAW_OPERATION(pContext, pThisDisplay);
  160. // Prepare any data necessary to clear the render target
  161. if ((lpcd2->dwFlags & D3DCLEAR_TARGET) &&
  162. (pContext->pSurfRenderInt != NULL))
  163. {
  164. color = lpcd2->dwFillColor;
  165. // Clear depending on depth
  166. switch (pContext->pSurfRenderInt->dwPixelSize)
  167. {
  168. // 16 Bit colors come in as 32 Bit RGB Values
  169. // Color will be packed in the clear function
  170. case __GLINT_16BITPIXEL:
  171. if (pThisDisplay->ddpfDisplay.dwRBitMask == 0x7C00)
  172. {
  173. color = ((color & 0xf8) >> 3) |
  174. ((color & 0xf800) >> (16 - 10)) |
  175. ((color & 0xf80000) >> (24 - 15));
  176. }
  177. else
  178. {
  179. color = ((color & 0xff) >> 3) |
  180. ((color & 0xfc00) >> (16 - 11)) |
  181. ((color & 0xf80000) >> (24 - 16));
  182. }
  183. break;
  184. case __GLINT_24BITPIXEL:
  185. DISPDBG((ERRLVL,"P3 doesn't support 24 bpp render target"));
  186. break;
  187. default:
  188. break;
  189. }
  190. } // if (lpcd2->dwFlags & D3DCLEAR_TARGET)
  191. // Prepare any data necessary to clear the depth buffer
  192. if ((lpcd2->dwFlags & D3DCLEAR_ZBUFFER) &&
  193. (pContext->pSurfZBufferInt != NULL))
  194. {
  195. float fDepth;
  196. DDPIXELFORMAT* pPixFormat = &pContext->pSurfZBufferInt->pixFmt;
  197. DWORD dwZBitDepth = pPixFormat->dwZBufferBitDepth;
  198. // Find the depth bits, remembering to remove any stencil bits.
  199. if (pPixFormat->dwFlags & DDPF_STENCILBUFFER)
  200. {
  201. dwZBitDepth -= pPixFormat->dwStencilBitDepth;
  202. }
  203. dwDepthMask = (0xFFFFFFFF >> (32 - dwZBitDepth));
  204. // 32 bit depth buffers on Perm3 are really
  205. // limited to 31 bits of precision
  206. if (dwZBitDepth == 32)
  207. {
  208. dwDepthMask = dwDepthMask >> 1;
  209. }
  210. if (lpcd2->dvFillDepth == 1.0f)
  211. {
  212. dwDepthValue = dwDepthMask;
  213. }
  214. else
  215. {
  216. fDepth = lpcd2->dvFillDepth * (float)dwDepthMask;
  217. // This is a hardware dependency on how the Perm3 handles the
  218. // limited precision of 32bit floats(24 bits of mantissa) and
  219. // converts the value into a 32bit z buffer value. This doesn't
  220. // happen with any other z bit depth but 32.
  221. if (dwZBitDepth == 32)
  222. {
  223. fDepth += 0.5f;
  224. }
  225. myFtoi((int*)&dwDepthValue, fDepth);
  226. }
  227. // As we are fast-block filling, make sure we copy the
  228. // Mask to the top bits.
  229. switch (pContext->pSurfZBufferInt->dwPixelSize)
  230. {
  231. case __GLINT_16BITPIXEL:
  232. dwDepthMask &= 0xFFFF;
  233. dwDepthMask |= (dwDepthMask << 16);
  234. break;
  235. case __GLINT_8BITPIXEL:
  236. dwDepthMask &= 0xFF;
  237. dwDepthMask |= dwDepthMask << 8;
  238. dwDepthMask |= dwDepthMask << 16;
  239. break;
  240. }
  241. if (pThisDisplay->pGLInfo->bDRAMBoard)
  242. {
  243. // Check for a DRAM fill that the chip isn't emulating.
  244. Bytes[0] = (BYTE)(dwDepthMask & 0xFF);
  245. Bytes[1] = (BYTE)((dwDepthMask & 0xFF00) >> 8);
  246. Bytes[2] = (BYTE)((dwDepthMask & 0xFF0000) >> 16);
  247. Bytes[3] = (BYTE)((dwDepthMask & 0xFF000000) >> 24);
  248. if (((Bytes[0] != 0) && (Bytes[0] != 0xFF)) ||
  249. ((Bytes[1] != 0) && (Bytes[1] != 0xFF)) ||
  250. ((Bytes[2] != 0) && (Bytes[2] != 0xFF)) ||
  251. ((Bytes[3] != 0) && (Bytes[3] != 0xFF)))
  252. {
  253. bNoBlockFillZ = TRUE;
  254. }
  255. }
  256. DISPDBG((DBGLVL,"ZClear Value = 0x%x, ZClear Mask = 0x%x",
  257. dwDepthValue, dwDepthMask));
  258. } // if (lpcd2->dwFlags & D3DCLEAR_ZBUFFER)
  259. // Prepare any data necessary to clear the stencil buffer
  260. if ((lpcd2->dwFlags & D3DCLEAR_STENCIL) &&
  261. (pContext->pSurfZBufferInt != NULL))
  262. {
  263. int dwShiftCount = 0;
  264. DDPIXELFORMAT* pPixFormat = &pContext->pSurfZBufferInt->pixFmt;
  265. // Find out where to shift the
  266. dwStencilMask = pPixFormat->dwStencilBitMask;
  267. if (dwStencilMask != 0)
  268. {
  269. while ((dwStencilMask & 0x1) == 0)
  270. {
  271. dwStencilMask >>= 1;
  272. dwShiftCount++;
  273. }
  274. dwStencilValue = (lpcd2->dwFillStencil << dwShiftCount);
  275. dwStencilMask = pPixFormat->dwStencilBitMask;
  276. // As we are fast-block filling, make sure we copy the
  277. // Mask to the top bits.
  278. switch (pContext->pSurfZBufferInt->dwPixelSize)
  279. {
  280. case __GLINT_16BITPIXEL:
  281. dwStencilMask &= 0xFFFF;
  282. dwStencilMask |= (dwStencilMask << 16);
  283. break;
  284. case __GLINT_8BITPIXEL:
  285. dwStencilMask &= 0xFF;
  286. dwStencilMask |= dwStencilMask << 8;
  287. dwStencilMask |= dwStencilMask << 16;
  288. break;
  289. }
  290. DISPDBG((DBGLVL,"Stencil Clear Value = 0x%x, Stencil Mask = 0x%x",
  291. dwStencilValue, dwStencilMask));
  292. }
  293. else
  294. {
  295. DISPDBG((ERRLVL,"ERROR: Stencil mask is not valid!"));
  296. dwStencilValue = 0;
  297. dwStencilMask = 0;
  298. }
  299. if (pThisDisplay->pGLInfo->bDRAMBoard)
  300. {
  301. // Check for a DRAM fill that the chip isn't emulating.
  302. Bytes[0] = (BYTE)(dwStencilMask & 0xFF);
  303. Bytes[1] = (BYTE)((dwStencilMask & 0xFF00) >> 8);
  304. Bytes[2] = (BYTE)((dwStencilMask & 0xFF0000) >> 16);
  305. Bytes[3] = (BYTE)((dwStencilMask & 0xFF000000) >> 24);
  306. if (((Bytes[0] != 0) && (Bytes[0] != 0xFF)) ||
  307. ((Bytes[1] != 0) && (Bytes[1] != 0xFF)) ||
  308. ((Bytes[2] != 0) && (Bytes[2] != 0xFF)) ||
  309. ((Bytes[3] != 0) && (Bytes[3] != 0xFF)))
  310. {
  311. bNoBlockFillStencil = TRUE;
  312. }
  313. }
  314. } // if (lpcd2->dwFlags & D3DCLEAR_STENCIL)
  315. // Loop through each clearing rect and perform the clearing hw operations
  316. i = dwNumRects;
  317. while (i-- > 0)
  318. {
  319. if (bComputeIntersections)
  320. {
  321. // Compute intersection between the viewport and the incoming
  322. // RECTLs. If no intersection exists skip into next one.
  323. if (!__OP_IntersectRectl(&rect, &rect_vwport, &lpcd2->Rects[i]))
  324. {
  325. // No intersection, so skip it
  326. goto Next_Rectl_To_Clear;
  327. }
  328. }
  329. else
  330. {
  331. // We already have the rects we need to clear, so
  332. // just use them in reverse order
  333. rect.left = lpcd2->Rects[i].left;
  334. rect.right = lpcd2->Rects[i].right;
  335. rect.top = lpcd2->Rects[i].top;
  336. rect.bottom = lpcd2->Rects[i].bottom;
  337. }
  338. // Clear the frame buffer
  339. if ((lpcd2->dwFlags & D3DCLEAR_TARGET) &&
  340. (pContext->pSurfRenderInt != NULL))
  341. {
  342. P3RX_UPDATE_WRITE_MASK(__GLINT_ALL_WRITEMASKS_SET);
  343. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  344. if (pContext->Flags & SURFACE_ANTIALIAS)
  345. {
  346. RECTL Temp = rect;
  347. Temp.left *= 2;
  348. Temp.right *= 2;
  349. Temp.top *= 2;
  350. Temp.bottom *= 2;
  351. _DD_BLT_P3Clear_AA(pThisDisplay,
  352. &Temp,
  353. pContext->dwAliasBackBuffer -
  354. pThisDisplay->dwScreenFlatAddr,
  355. color,
  356. FALSE,
  357. pContext->pSurfRenderInt->dwPatchMode,
  358. pContext->pSurfRenderInt->dwPixelPitch,
  359. pContext->pSurfRenderInt->pixFmt.dwRGBBitCount,
  360. pContext->pSurfRenderInt->ddsCapsInt);
  361. }
  362. else
  363. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  364. {
  365. _DD_BLT_P3Clear(pThisDisplay,
  366. &rect,
  367. color,
  368. FALSE,
  369. FALSE,
  370. pContext->pSurfRenderInt->fpVidMem,
  371. pContext->pSurfRenderInt->dwPatchMode,
  372. pContext->pSurfRenderInt->dwPixelPitch,
  373. pContext->pSurfRenderInt->pixFmt.dwRGBBitCount);
  374. }
  375. }
  376. // Clear the z buffer
  377. if ((lpcd2->dwFlags & D3DCLEAR_ZBUFFER) &&
  378. (pContext->pSurfZBufferInt != NULL) )
  379. {
  380. P3RX_UPDATE_WRITE_MASK(dwDepthMask);
  381. if (bNoBlockFillZ)
  382. {
  383. P3_DMA_GET_BUFFER_ENTRIES(4);
  384. SEND_P3_DATA(FBSoftwareWriteMask, dwDepthMask);
  385. SEND_P3_DATA(FBDestReadMode,
  386. P3RX_FBDESTREAD_READENABLE(__PERMEDIA_ENABLE) |
  387. P3RX_FBDESTREAD_ENABLE0(__PERMEDIA_ENABLE));
  388. P3_DMA_COMMIT_BUFFER();
  389. }
  390. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  391. if (pContext->Flags & SURFACE_ANTIALIAS)
  392. {
  393. RECTL Temp = rect;
  394. Temp.left *= 2;
  395. Temp.right *= 2;
  396. Temp.top *= 2;
  397. Temp.bottom *= 2;
  398. _DD_BLT_P3Clear_AA(pThisDisplay,
  399. &Temp,
  400. pContext->dwAliasZBuffer -
  401. pThisDisplay->dwScreenFlatAddr,
  402. dwDepthValue,
  403. bNoBlockFillZ,
  404. pContext->pSurfZBufferInt->dwPatchMode,
  405. pContext->pSurfZBufferInt->dwPixelPitch,
  406. pContext->pSurfZBufferInt->pixFmt.dwRGBBitCount,
  407. pContext->pSurfZBufferInt->ddsCapsInt);
  408. }
  409. else
  410. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  411. {
  412. _DD_BLT_P3Clear(pThisDisplay,
  413. &rect,
  414. dwDepthValue,
  415. bNoBlockFillZ,
  416. TRUE,
  417. pContext->pSurfZBufferInt->fpVidMem,
  418. pContext->pSurfZBufferInt->dwPatchMode,
  419. pContext->pSurfZBufferInt->dwPixelPitch,
  420. pContext->pSurfZBufferInt->pixFmt.dwRGBBitCount
  421. );
  422. }
  423. if (bNoBlockFillZ)
  424. {
  425. P3_DMA_GET_BUFFER_ENTRIES(4);
  426. SEND_P3_DATA(FBSoftwareWriteMask, __GLINT_ALL_WRITEMASKS_SET);
  427. SEND_P3_DATA(FBDestReadMode, __PERMEDIA_DISABLE);
  428. P3_DMA_COMMIT_BUFFER();
  429. }
  430. }
  431. // Clear the stencil buffer
  432. if ((lpcd2->dwFlags & D3DCLEAR_STENCIL) &&
  433. (pContext->pSurfZBufferInt != NULL) )
  434. {
  435. P3RX_UPDATE_WRITE_MASK(dwStencilMask);
  436. if (bNoBlockFillStencil)
  437. {
  438. P3_DMA_GET_BUFFER_ENTRIES(4);
  439. SEND_P3_DATA(FBSoftwareWriteMask, dwStencilMask);
  440. SEND_P3_DATA(FBDestReadMode,
  441. P3RX_FBDESTREAD_READENABLE(__PERMEDIA_ENABLE) |
  442. P3RX_FBDESTREAD_ENABLE0(__PERMEDIA_ENABLE));
  443. P3_DMA_COMMIT_BUFFER();
  444. }
  445. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  446. if (pContext->Flags & SURFACE_ANTIALIAS)
  447. {
  448. RECTL Temp = rect;
  449. Temp.left *= 2;
  450. Temp.right *= 2;
  451. Temp.top *= 2;
  452. Temp.bottom *= 2;
  453. _DD_BLT_P3Clear_AA(pThisDisplay,
  454. &Temp,
  455. pContext->dwAliasZBuffer -
  456. pThisDisplay->dwScreenFlatAddr,
  457. dwStencilValue,
  458. bNoBlockFillStencil,
  459. pContext->pSurfZBufferInt->dwPatchMode,
  460. pContext->pSurfZBufferInt->dwPixelPitch,
  461. pContext->pSurfZBufferInt->pixFmt.dwRGBBitCount,
  462. pContext->pSurfZBufferInt->ddsCapsInt
  463. );
  464. }
  465. else
  466. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  467. {
  468. _DD_BLT_P3Clear(pThisDisplay,
  469. &rect,
  470. dwStencilValue,
  471. bNoBlockFillStencil,
  472. TRUE,
  473. pContext->pSurfZBufferInt->fpVidMem,
  474. pContext->pSurfZBufferInt->dwPatchMode,
  475. pContext->pSurfZBufferInt->dwPixelPitch,
  476. pContext->pSurfZBufferInt->pixFmt.dwRGBBitCount
  477. );
  478. }
  479. if (bNoBlockFillStencil)
  480. {
  481. P3_DMA_GET_BUFFER_ENTRIES(4);
  482. SEND_P3_DATA(FBSoftwareWriteMask, __GLINT_ALL_WRITEMASKS_SET);
  483. SEND_P3_DATA(FBDestReadMode, __PERMEDIA_DISABLE);
  484. P3_DMA_COMMIT_BUFFER();
  485. }
  486. }
  487. Next_Rectl_To_Clear:
  488. ;
  489. } // while
  490. // Make sure the WriteMask is reset to it's default value
  491. {
  492. P3_DMA_GET_BUFFER_ENTRIES(4);
  493. SEND_P3_DATA(FBHardwareWriteMask, __GLINT_ALL_WRITEMASKS_SET);
  494. SEND_P3_DATA(FBDestReadMode, __PERMEDIA_DISABLE);
  495. P3_DMA_COMMIT_BUFFER();
  496. }
  497. DBG_CB_EXIT(_D3D_OP_Clear2, DD_OK);
  498. return;
  499. } // _D3D_OP_Clear2
  500. //-----------------------------------------------------------------------------
  501. //
  502. // _D3D_OP_TextureBlt
  503. //
  504. // This function processes the D3DDP2OP_TEXBLT DP2 command token.
  505. //
  506. //-----------------------------------------------------------------------------
  507. VOID _D3D_OP_TextureBlt(P3_D3DCONTEXT* pContext,
  508. P3_THUNKEDDATA*pThisDisplay,
  509. D3DHAL_DP2TEXBLT* pBlt)
  510. {
  511. LPDDRAWI_DDRAWSURFACE_LCL pSrcLcl;
  512. LPDDRAWI_DDRAWSURFACE_LCL pDestLcl;
  513. P3_SURF_INTERNAL* pSrcTexture;
  514. P3_SURF_INTERNAL* pDestTexture;
  515. P3_SURF_FORMAT* pFormatSource;
  516. P3_SURF_FORMAT* pFormatDest;
  517. MIPTEXTURE *pSrcMipLevel, *pDstMipLevel;
  518. RECTL rSrc, rDest;
  519. int iMaxLogWidth, iCurrLogWidth;
  520. int iSrcLOD, iDestLOD, iCurrSrcLOD, iCurrDstLOD;
  521. BOOL bMipMap, bMipMapLevelsMatch;
  522. DISPDBG((DBGLVL, "TextureBlt Source %d Dest %d",
  523. pBlt->dwDDSrcSurface,
  524. pBlt->dwDDDestSurface));
  525. if (0 == pBlt->dwDDSrcSurface)
  526. {
  527. DISPDBG((ERRLVL,"Invalid handle TexBlt from %08lx to %08lx",
  528. pBlt->dwDDSrcSurface,pBlt->dwDDDestSurface));
  529. return;
  530. }
  531. // Get the source texture structure pointer
  532. pSrcTexture = GetSurfaceFromHandle(pContext, pBlt->dwDDSrcSurface);
  533. // Check that the source texture is valid
  534. if (pSrcTexture == NULL)
  535. {
  536. DISPDBG((ERRLVL, "ERROR: Source texture %d is invalid!",
  537. pBlt->dwDDSrcSurface));
  538. return;
  539. }
  540. // Validate the destination texture handle
  541. if (0 == pBlt->dwDDDestSurface)
  542. {
  543. #if DX7_TEXMANAGEMENT
  544. // If we do texture management then a destination handle of 0
  545. // has the special meaning of preloading the source texture.
  546. if (!_D3D_TM_Preload_Tex_IntoVidMem(pContext, pSrcTexture))
  547. {
  548. DISPDBG((ERRLVL,"_D3D_OP_TextureBlt unable to "
  549. "preload texture"));
  550. }
  551. return;
  552. #else
  553. // If there's no driver texture managament support we can't go
  554. // on if the destination handle is 0
  555. DISPDBG((ERRLVL,"Invalid handle TexBlt from %08lx to %08lx",
  556. pBlt->dwDDSrcSurface,pBlt->dwDDDestSurface));
  557. return;
  558. #endif
  559. }
  560. // Get the destination texture structure pointer for regular TexBlts
  561. pDestTexture = GetSurfaceFromHandle(pContext, pBlt->dwDDDestSurface);
  562. // Check that the destination texture is valid
  563. if (pDestTexture == NULL)
  564. {
  565. DISPDBG((ERRLVL, "ERROR: Dest texture %d is invalid!",
  566. pBlt->dwDDDestSurface));
  567. return;
  568. }
  569. // Make sure the textures are of the same proportion
  570. if ((pSrcTexture->wWidth * pDestTexture->wHeight) !=
  571. (pSrcTexture->wHeight * pDestTexture->wWidth))
  572. {
  573. DISPDBG((ERRLVL, "ERROR: TEXBLT the src and dest textures are not of the same proportion"));
  574. return;
  575. }
  576. // It is possible that the source and destination textures may contain
  577. // different number of mipmap levels. In this case, the driver is
  578. // expected to BitBlt the common levels. For example, if a 256x256 source
  579. // texture has 8 mipmap levels, and if the destination is a 64x64 texture
  580. // with 6 levels, then the driver should BitBlt the 6 corresponding levels
  581. // from the source. The driver can expect the dimensions of the top mip
  582. // level of destination texture to be always equal to or lesser than the
  583. // dimensions of the top mip level of the source texture.
  584. // It might also be the case that only one of the textures is mipmapped
  585. // Since we keep all relevant info also in the MipLevels substructre for
  586. // the surface, we can treat both surfaces as mipmapped even if only
  587. // one of them was created as such and proceed with the TexBlt.
  588. if (pSrcTexture->bMipMap || pDestTexture->bMipMap)
  589. {
  590. bMipMap = TRUE;
  591. iMaxLogWidth = max(pSrcTexture->logWidth, pDestTexture->logWidth);
  592. iCurrLogWidth = iMaxLogWidth;
  593. iSrcLOD = 0; // start LOD for src
  594. iDestLOD = 0; // start LOD for dest
  595. }
  596. else
  597. {
  598. // just one level
  599. bMipMap = FALSE; // No mipmapping cases to be handled
  600. iMaxLogWidth = iCurrLogWidth = iSrcLOD = iDestLOD = 0;
  601. }
  602. // Init the rects from and into which we will blt . This is top level
  603. // mipmap or non-mipmap texture, just use rect from Blt.
  604. rSrc = pBlt->rSrc;
  605. // Create a destination rectangle for compatibility
  606. // with the DD blitting function we are calling.
  607. rDest.left = pBlt->pDest.x;
  608. rDest.top = pBlt->pDest.y;
  609. rDest.right = (pBlt->rSrc.right - pBlt->rSrc.left) + rDest.left;
  610. rDest.bottom = (pBlt->rSrc.bottom - pBlt->rSrc.top) + rDest.top;
  611. // Traverse all the mip map levels and try to match them for a blt to be
  612. // done. If no mipmaps are present just do for the "first" and only
  613. // levels present.
  614. do
  615. {
  616. DISPDBG((DBGLVL,"TEXBLT iteration %d %d %d %d",
  617. iMaxLogWidth,iCurrLogWidth,iSrcLOD,iDestLOD));
  618. // Get the local surface pointers and make sure the level sizes
  619. // match in the case of mip map Texblts.
  620. if (bMipMap)
  621. {
  622. bMipMapLevelsMatch = FALSE;
  623. // Verify you only look at valid mipmap levels - they might
  624. // be incomplete (and we want not to AV or access garbage!)
  625. // for example, a source 256x256 texture may contain 5 levels,
  626. // but the destination 256x256 texture may contain 8. The
  627. // driver is expected to safely handle this case, but it is
  628. // not expected to produce correct results
  629. if ((iSrcLOD < pSrcTexture->iMipLevels) &&
  630. (iDestLOD < pDestTexture->iMipLevels))
  631. {
  632. DISPDBG((DBGLVL,"Checking match! %d vs. %d",
  633. pSrcTexture->MipLevels[iSrcLOD].logWidth,
  634. pDestTexture->MipLevels[iDestLOD].logWidth));
  635. // Do we currently have two levels that match in size ?
  636. bMipMapLevelsMatch =
  637. ( pSrcTexture->MipLevels[iSrcLOD].logWidth ==
  638. pDestTexture->MipLevels[iDestLOD].logWidth);
  639. }
  640. // Record which levels are we currently blitting
  641. iCurrSrcLOD = iSrcLOD;
  642. iCurrDstLOD = iDestLOD;
  643. // Get ready for next loop by updating the LODs to use
  644. // increment LOD# if we are currently looking at a level
  645. // equal or smaller to mip maps level 0 size
  646. if (iCurrLogWidth <= pSrcTexture->logWidth)
  647. {
  648. iSrcLOD++;
  649. }
  650. if (iCurrLogWidth <= pDestTexture->logWidth)
  651. {
  652. iDestLOD++;
  653. }
  654. // Decrease the width into next smaller level
  655. iCurrLogWidth--;
  656. }
  657. else
  658. {
  659. // Single level blt - we set bMipMapLevelsMatch in order to blt it!
  660. bMipMapLevelsMatch = TRUE;
  661. iCurrSrcLOD = 0;
  662. iCurrDstLOD = 0;
  663. }
  664. if (bMipMapLevelsMatch)
  665. {
  666. // Switch to the DirectDraw context
  667. DDRAW_OPERATION(pContext, pThisDisplay);
  668. DISPDBG((DBGLVL,"Blitting level %d into level %d",
  669. iCurrSrcLOD,
  670. iCurrDstLOD));
  671. pSrcMipLevel = &pSrcTexture->MipLevels[iCurrSrcLOD];
  672. pDstMipLevel = &pDestTexture->MipLevels[iCurrDstLOD];
  673. ///////////////////////////////////////////////////////////////////
  674. // Here we handle all possible blt cases between different types
  675. // of memory and different scenarios of managed/unmanaged surfaces
  676. ///////////////////////////////////////////////////////////////////
  677. #if DX7_TEXMANAGEMENT
  678. if ((0 == (pDestTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)) &&
  679. (0 == (pSrcTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)) )
  680. #endif // DX7_TEXMANAGEMENT
  681. {
  682. //----------------------------------
  683. //----------------------------------
  684. // TEXBLT among non-managed textures
  685. //----------------------------------
  686. //----------------------------------
  687. if ((pSrcTexture->Location == SystemMemory) &&
  688. (pDestTexture->Location == VideoMemory))
  689. {
  690. //----------------------------
  691. // Do the system->videomem blt
  692. //----------------------------
  693. _DD_P3Download(pThisDisplay,
  694. pSrcMipLevel->fpVidMem,
  695. pDstMipLevel->fpVidMem,
  696. pSrcTexture->dwPatchMode,
  697. pDestTexture->dwPatchMode,
  698. pSrcMipLevel->lPitch,
  699. pDstMipLevel->lPitch,
  700. pDstMipLevel->P3RXTextureMapWidth.Width,
  701. pDestTexture->dwPixelSize,
  702. &rSrc,
  703. &rDest);
  704. }
  705. else if ((pSrcTexture->Location == VideoMemory) &&
  706. (pDestTexture->Location == VideoMemory))
  707. {
  708. //------------------------------
  709. // Do the videomem->videomem blt
  710. //------------------------------
  711. _DD_BLT_P3CopyBlt(pThisDisplay,
  712. pSrcMipLevel->fpVidMem,
  713. pDstMipLevel->fpVidMem,
  714. pSrcTexture->dwPatchMode,
  715. pDestTexture->dwPatchMode,
  716. pSrcMipLevel->P3RXTextureMapWidth.Width,
  717. pDstMipLevel->P3RXTextureMapWidth.Width,
  718. pSrcMipLevel->dwOffsetFromMemoryBase,
  719. pDstMipLevel->dwOffsetFromMemoryBase,
  720. pDestTexture->dwPixelSize,
  721. &rSrc,
  722. &rDest);
  723. }
  724. else if ((pSrcTexture->Location == AGPMemory) &&
  725. (pDestTexture->Location == VideoMemory))
  726. {
  727. //-------------------------------
  728. // Do the AGP mem -> videomem blt
  729. //-------------------------------
  730. DDCOLORKEY ddck_dummy = { 0 , 0 };
  731. // We use the strecth blt because it handles AGP source
  732. // surfaces, not becuase we should stretch the surface in any way
  733. _DD_P3BltStretchSrcChDstCh(
  734. pThisDisplay,
  735. // src data
  736. pSrcMipLevel->fpVidMem,
  737. pSrcTexture->pFormatSurface,
  738. pSrcTexture->dwPixelSize,
  739. pSrcMipLevel->wWidth,
  740. pSrcMipLevel->wHeight,
  741. pSrcMipLevel->P3RXTextureMapWidth.Width,
  742. pSrcMipLevel->P3RXTextureMapWidth.Layout,
  743. pSrcMipLevel->dwOffsetFromMemoryBase,
  744. pSrcTexture->dwFlagsInt,
  745. &pSrcTexture->pixFmt,
  746. 1, // src IS AGP, otherwise we
  747. //would'nt call this
  748. // dest data
  749. pDstMipLevel->fpVidMem,
  750. pDestTexture->pFormatSurface,
  751. pDestTexture->dwPixelSize,
  752. pDstMipLevel->wWidth,
  753. pDstMipLevel->wHeight,
  754. pDstMipLevel->P3RXTextureMapWidth.Width,
  755. pDstMipLevel->P3RXTextureMapWidth.Layout,
  756. pDstMipLevel->dwOffsetFromMemoryBase,
  757. 0, // dwBltFlags no special blt effects
  758. 0, // dwBltDDFX no special effects info
  759. ddck_dummy, // BltSrcColorKey dummy arg
  760. ddck_dummy, // BltDestColorKey dummy arg
  761. &rSrc,
  762. &rDest
  763. );
  764. }
  765. else
  766. {
  767. DISPDBG((ERRLVL,"Non-managed Tex Blt variation unimplemented! "
  768. "(from %d into %d)",
  769. pSrcTexture->Location,
  770. pDestTexture->Location));
  771. }
  772. }
  773. #if DX7_TEXMANAGEMENT
  774. else if (pSrcTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
  775. {
  776. //----------------------------------
  777. //----------------------------------
  778. // TEXBLT from a managed texture
  779. //----------------------------------
  780. //----------------------------------
  781. if ((pDestTexture->Location == SystemMemory) ||
  782. (pDestTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE))
  783. {
  784. //-------------------------------------------------
  785. // Do the Managed surf -> sysmem | managed surf blt
  786. //-------------------------------------------------
  787. // make sure we'll reload the vidmem copy of the dest surf
  788. if (pDestTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
  789. {
  790. __OP_MarkManagedSurfDirty(pContext,
  791. pBlt->dwDDDestSurface,
  792. pDestTexture);
  793. }
  794. _DD_BLT_SysMemToSysMemCopy(
  795. pSrcMipLevel->fpVidMem,
  796. pSrcMipLevel->lPitch,
  797. pSrcTexture->dwBitDepth,
  798. pDstMipLevel->fpVidMem,
  799. pDstMipLevel->lPitch,
  800. pDestTexture->dwBitDepth,
  801. &rSrc,
  802. &rDest);
  803. }
  804. else if (pDestTexture->Location == VideoMemory)
  805. {
  806. //-------------------------------------------------
  807. // Do the Managed surf -> vidmem surf blt
  808. //-------------------------------------------------
  809. // This might be optimized by doing a vidmem->vidmem
  810. // when the source managed texture has a vidmem copy
  811. _DD_P3Download(pThisDisplay,
  812. pSrcMipLevel->fpVidMem,
  813. pDstMipLevel->fpVidMem,
  814. pSrcTexture->dwPatchMode,
  815. pDestTexture->dwPatchMode,
  816. pSrcMipLevel->lPitch,
  817. pDstMipLevel->lPitch,
  818. pDstMipLevel->P3RXTextureMapWidth.Width,
  819. pDestTexture->dwPixelSize,
  820. &rSrc,
  821. &rDest);
  822. }
  823. else
  824. {
  825. DISPDBG((ERRLVL,"Src-managed Tex Blt variation unimplemented! "
  826. "(from %d into %d)",
  827. pSrcTexture->Location,
  828. pDestTexture->Location));
  829. }
  830. }
  831. else if (pDestTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
  832. {
  833. //--------------------------------------------------------------
  834. //--------------------------------------------------------------
  835. // TEXBLT into a managed texture (except from a managed texture)
  836. //--------------------------------------------------------------
  837. //--------------------------------------------------------------
  838. // managed->managed is handled in the previous case
  839. if (pSrcTexture->Location == SystemMemory)
  840. {
  841. //-------------------------------------------------
  842. // Do the sysmem surf -> managed surf blt
  843. //-------------------------------------------------
  844. // make sure we'll reload the vidmem copy of the dest surf
  845. __OP_MarkManagedSurfDirty(pContext,
  846. pBlt->dwDDDestSurface,
  847. pDestTexture);
  848. _DD_BLT_SysMemToSysMemCopy(
  849. pSrcMipLevel->fpVidMem,
  850. pSrcMipLevel->lPitch,
  851. pSrcTexture->dwBitDepth,
  852. pDstMipLevel->fpVidMem,
  853. pDstMipLevel->lPitch,
  854. pDestTexture->dwBitDepth,
  855. &rSrc,
  856. &rDest);
  857. }
  858. else if (pSrcTexture->Location == VideoMemory)
  859. {
  860. //-------------------------------------------------
  861. // Do the vidmem surf -> Managed surf blt
  862. //-------------------------------------------------
  863. if (0 != pSrcMipLevel->fpVidMemTM)
  864. {
  865. // Destination is already in vidmem so instead of
  866. // "dirtying" the managed texture lets do the
  867. // vidmem->vidmem blt which is faster than doing the
  868. // update later (in the hope we'll really use it)
  869. _DD_BLT_P3CopyBlt(pThisDisplay,
  870. pSrcMipLevel->fpVidMem,
  871. pDstMipLevel->fpVidMemTM,
  872. pSrcTexture->dwPatchMode,
  873. pDestTexture->dwPatchMode,
  874. pSrcMipLevel->P3RXTextureMapWidth.Width,
  875. pDstMipLevel->P3RXTextureMapWidth.Width,
  876. pSrcMipLevel->dwOffsetFromMemoryBase,
  877. pDstMipLevel->dwOffsetFromMemoryBase,
  878. pDestTexture->dwPixelSize,
  879. &rSrc,
  880. &rDest);
  881. }
  882. else
  883. {
  884. // make sure we'll reload the
  885. // vidmem copy of the dest surf
  886. __OP_MarkManagedSurfDirty(pContext,
  887. pBlt->dwDDDestSurface,
  888. pDestTexture);
  889. }
  890. // Do slow mem mapped framebuffer blt into sysmem
  891. // The source surface lives in video mem so we need to get a
  892. // "real" sysmem address for it:
  893. _DD_BLT_SysMemToSysMemCopy(
  894. D3DMIPLVL_GETPOINTER(pSrcMipLevel, pThisDisplay),
  895. pSrcMipLevel->lPitch,
  896. pSrcTexture->dwBitDepth,
  897. pDstMipLevel->fpVidMem,
  898. pDstMipLevel->lPitch,
  899. pDestTexture->dwBitDepth,
  900. &rSrc,
  901. &rDest);
  902. }
  903. else if (pSrcTexture->Location == AGPMemory)
  904. {
  905. // make sure we'll reload the vidmem copy of the dest surf
  906. __OP_MarkManagedSurfDirty(pContext,
  907. pBlt->dwDDDestSurface,
  908. pDestTexture);
  909. _DD_BLT_SysMemToSysMemCopy(
  910. pSrcMipLevel->fpVidMem,
  911. pSrcMipLevel->lPitch,
  912. pSrcTexture->dwBitDepth,
  913. pDstMipLevel->fpVidMem,
  914. pDstMipLevel->lPitch,
  915. pDestTexture->dwBitDepth,
  916. &rSrc,
  917. &rDest);
  918. }
  919. else
  920. {
  921. DISPDBG((ERRLVL,"Dest-managed Tex Blt variation unimplemented! "
  922. "(from %d into %d)",
  923. pSrcTexture->Location,
  924. pDestTexture->Location));
  925. }
  926. }
  927. else
  928. {
  929. DISPDBG((ERRLVL,"Tex Blt variation unimplemented! "
  930. "(from %d into %d)",
  931. pSrcTexture->Location,
  932. pDestTexture->Location));
  933. }
  934. #endif // DX7_TEXMANAGEMENT
  935. // Switch back to the Direct3D context
  936. D3D_OPERATION(pContext, pThisDisplay);
  937. } // if (bMipMapLevelsMatch)
  938. // Update transfer rectangles if mip mapping
  939. if (bMipMap)
  940. {
  941. DWORD right, bottom;
  942. // Update source rectangle , the regions to be copied in mipmap
  943. // sub-levels can be obtained by dividing rSrc and pDest by
  944. // 2 at each level.
  945. rSrc.left >>= 1;
  946. rSrc.top >>= 1;
  947. right = (rSrc.right + 1) >> 1;
  948. bottom = (rSrc.bottom + 1) >> 1;
  949. rSrc.right = ((right - rSrc.left) < 1) ? (rSrc.left + 1) : (right);
  950. rSrc.bottom = ((bottom - rSrc.top ) < 1) ? (rSrc.top + 1) : (bottom);
  951. // Update destination rectangle
  952. rDest.left >>= 1;
  953. rDest.top >>= 1;
  954. right = (rDest.right + 1) >> 1;
  955. bottom = (rDest.bottom + 1) >> 1;
  956. rDest.right = ((right - rDest.left) < 1) ? (rDest.left + 1) : (right);
  957. rDest.bottom = ((bottom - rDest.top ) < 1) ? (rDest.top + 1) : (bottom);
  958. }
  959. } while (bMipMap && ((iSrcLOD < pSrcTexture->iMipLevels) &&
  960. (iDestLOD < pDestTexture->iMipLevels))); // do until we're done looking at 1x1
  961. } // _D3D_OP_TextureBlt
  962. //-----------------------------------------------------------------------------
  963. //
  964. // _D3D_OP_SetRenderTarget
  965. //
  966. // Sets up the hw for the chosen render target and depth buffer
  967. //
  968. //-----------------------------------------------------------------------------
  969. HRESULT
  970. _D3D_OP_SetRenderTarget(
  971. P3_D3DCONTEXT* pContext,
  972. P3_SURF_INTERNAL* pRenderInt,
  973. P3_SURF_INTERNAL* pZBufferInt,
  974. BOOL bNewAliasBuffers)
  975. {
  976. P3_SOFTWARECOPY* pSoftP3RX = &pContext->SoftCopyGlint;
  977. P3_THUNKEDDATA *pThisDisplay = pContext->pThisDisplay;
  978. DWORD AAMultiplier = 1;
  979. P3_DMA_DEFS();
  980. DBG_ENTRY(_D3D_OP_SetRenderTarget);
  981. // Verify the render target is in video memory
  982. if (pRenderInt)
  983. {
  984. if (pRenderInt->ddsCapsInt.dwCaps & DDSCAPS_SYSTEMMEMORY)
  985. {
  986. DISPDBG((ERRLVL, "ERROR: Render Surface in SYSTEM MEMORY"));
  987. return DDERR_GENERIC;
  988. }
  989. }
  990. else
  991. {
  992. // Must have a render target
  993. DISPDBG((ERRLVL, "ERROR: Render Surface is NULL"));
  994. return DDERR_GENERIC;
  995. }
  996. // If a Z Buffer verify it
  997. if (pZBufferInt)
  998. {
  999. if (pZBufferInt->ddsCapsInt.dwCaps & DDSCAPS_SYSTEMMEMORY)
  1000. {
  1001. DISPDBG((ERRLVL, "ERROR: Z Surface in SYSTEM MEMORY, failing"));
  1002. return DDERR_GENERIC;
  1003. }
  1004. }
  1005. // Validate the RenderTarget to be 32 bit or 16 bit 565
  1006. if ((pRenderInt->pixFmt.dwRGBBitCount == 32 ) &&
  1007. (pRenderInt->pixFmt.dwRBitMask == 0x00FF0000) &&
  1008. (pRenderInt->pixFmt.dwGBitMask == 0x0000FF00) &&
  1009. (pRenderInt->pixFmt.dwBBitMask == 0x000000FF))
  1010. {
  1011. // were OK at 32bpp
  1012. }
  1013. else
  1014. if ((pRenderInt->pixFmt.dwRGBBitCount == 16 ) &&
  1015. (pRenderInt->pixFmt.dwRBitMask == 0xF800) &&
  1016. (pRenderInt->pixFmt.dwGBitMask == 0x07E0) &&
  1017. (pRenderInt->pixFmt.dwBBitMask == 0x001F))
  1018. {
  1019. // were OK at 16bpp
  1020. }
  1021. else
  1022. {
  1023. // we cant set our render target to this format !!!
  1024. DISPDBG((WRNLVL, " SRT Error !!!"));
  1025. DISPDBG((WRNLVL, " dwRGBBitCount: 0x%x",
  1026. pRenderInt->pixFmt.dwRGBBitCount));
  1027. DISPDBG((WRNLVL, " dwR/Y BitMask: 0x%x",
  1028. pRenderInt->pixFmt.dwRBitMask));
  1029. DISPDBG((WRNLVL, " dwG/U BitMask: 0x%x",
  1030. pRenderInt->pixFmt.dwGBitMask));
  1031. DISPDBG((WRNLVL, " dwB/V BitMask: 0x%x",
  1032. pRenderInt->pixFmt.dwBBitMask));
  1033. DISPDBG((WRNLVL, " dwRGBAlphaBitMask: 0x%x",
  1034. pRenderInt->pixFmt.dwRGBAlphaBitMask));
  1035. return DDERR_GENERIC;
  1036. }
  1037. #if DX8_MULTISAMPLING
  1038. // Decide whether antialising is requested and can be handled
  1039. if ((pContext->pSurfRenderInt->dwSampling) &&
  1040. (! _D3D_ST_CanRenderAntialiased(pContext, bNewAliasBuffers)))
  1041. {
  1042. return DDERR_OUTOFMEMORY;
  1043. }
  1044. #endif // DX8_MULTISAMPLING
  1045. // If we page flipped, clear the flag
  1046. pThisDisplay->bFlippedSurface = FALSE;
  1047. P3_DMA_GET_BUFFER();
  1048. P3_ENSURE_DX_SPACE(46);
  1049. WAIT_FIFO(26);
  1050. pContext->pSurfRenderInt = pRenderInt;
  1051. pContext->pSurfZBufferInt = pZBufferInt;
  1052. // Check for Z Buffer
  1053. if (pZBufferInt)
  1054. {
  1055. DDPIXELFORMAT* pZFormat = &pZBufferInt->pixFmt;
  1056. if( pThisDisplay->dwDXVersion >= DX6_RUNTIME)
  1057. {
  1058. // On DX6 we look in the pixel format for the depth and stencil info.
  1059. switch(pZFormat->dwZBufferBitDepth)
  1060. {
  1061. default:
  1062. DISPDBG((ERRLVL,"ERROR: Unknown Z Pixel format!"));
  1063. // Regard the buffer as 16 bit one and fall through
  1064. case 16:
  1065. if (pZFormat->dwStencilBitDepth == 1)
  1066. {
  1067. // 15 bit Z, 1 bit stencil
  1068. pSoftP3RX->P3RXLBReadFormat.StencilPosition = 0; // Ignored in this mode
  1069. pSoftP3RX->P3RXLBReadFormat.StencilWidth = P3RX_STENCIL_WIDTH_1;
  1070. pSoftP3RX->P3RXLBReadFormat.DepthWidth = P3RX_DEPTH_WIDTH_15;
  1071. pSoftP3RX->P3RXStencilMode.StencilWidth = P3RX_STENCIL_WIDTH_1;
  1072. pSoftP3RX->P3RXLBWriteFormat.StencilPosition = 0; // Ignored in this mode
  1073. pSoftP3RX->P3RXLBWriteFormat.StencilWidth = P3RX_STENCIL_WIDTH_1;
  1074. pSoftP3RX->P3RXLBWriteFormat.DepthWidth = P3RX_DEPTH_WIDTH_15;
  1075. pSoftP3RX->P3RXDepthMode.Width = P3RX_DEPTH_WIDTH_15;
  1076. pSoftP3RX->P3RXLBSourceReadMode.Packed16 = 1;
  1077. pSoftP3RX->P3RXLBDestReadMode.Packed16 = 1;
  1078. pSoftP3RX->P3RXLBWriteMode.Packed16 = 1;
  1079. pSoftP3RX->P3RXLBWriteMode.ByteEnables = 0x3;
  1080. }
  1081. else
  1082. {
  1083. // 16 bit Z, no stencil
  1084. pSoftP3RX->P3RXLBReadFormat.StencilPosition = 0; // Ignored in this mode
  1085. pSoftP3RX->P3RXLBReadFormat.StencilWidth = P3RX_STENCIL_WIDTH_0;
  1086. pSoftP3RX->P3RXStencilMode.StencilWidth = P3RX_STENCIL_WIDTH_0;
  1087. pSoftP3RX->P3RXLBReadFormat.DepthWidth = P3RX_DEPTH_WIDTH_16;
  1088. pSoftP3RX->P3RXLBWriteFormat.StencilPosition = 0; // Ignored in this mode
  1089. pSoftP3RX->P3RXLBWriteFormat.StencilWidth = P3RX_STENCIL_WIDTH_0;
  1090. pSoftP3RX->P3RXLBWriteFormat.DepthWidth = P3RX_DEPTH_WIDTH_16;
  1091. pSoftP3RX->P3RXDepthMode.Width = P3RX_DEPTH_WIDTH_16;
  1092. pSoftP3RX->P3RXLBWriteMode.ByteEnables = 0x3;
  1093. pSoftP3RX->P3RXLBSourceReadMode.Packed16 = 1;
  1094. pSoftP3RX->P3RXLBDestReadMode.Packed16 = 1;
  1095. pSoftP3RX->P3RXLBWriteMode.Packed16 = 1;
  1096. }
  1097. break;
  1098. case 32:
  1099. if (pZFormat->dwStencilBitDepth == 8)
  1100. {
  1101. // 24 bit Z, 8 bit stencil
  1102. pSoftP3RX->P3RXLBReadFormat.StencilPosition = P3RX_STENCIL_POSITION_24;
  1103. pSoftP3RX->P3RXLBReadFormat.StencilWidth = P3RX_STENCIL_WIDTH_8;
  1104. pSoftP3RX->P3RXStencilMode.StencilWidth = P3RX_STENCIL_WIDTH_8;
  1105. pSoftP3RX->P3RXLBReadFormat.DepthWidth = P3RX_DEPTH_WIDTH_24;
  1106. pSoftP3RX->P3RXLBWriteFormat.StencilPosition = P3RX_STENCIL_POSITION_24;
  1107. pSoftP3RX->P3RXLBWriteFormat.StencilWidth = P3RX_STENCIL_WIDTH_8;
  1108. pSoftP3RX->P3RXLBWriteFormat.DepthWidth = P3RX_DEPTH_WIDTH_24;
  1109. pSoftP3RX->P3RXDepthMode.Width = P3RX_DEPTH_WIDTH_24;
  1110. pSoftP3RX->P3RXLBWriteMode.ByteEnables = 0xF;
  1111. pSoftP3RX->P3RXLBSourceReadMode.Packed16 = 0;
  1112. pSoftP3RX->P3RXLBDestReadMode.Packed16 = 0;
  1113. pSoftP3RX->P3RXLBWriteMode.Packed16 = 0;
  1114. }
  1115. else
  1116. {
  1117. // 32 bit Z, no stencil
  1118. pSoftP3RX->P3RXLBReadFormat.StencilPosition = 0;
  1119. pSoftP3RX->P3RXLBReadFormat.StencilWidth = P3RX_STENCIL_WIDTH_0;
  1120. pSoftP3RX->P3RXStencilMode.StencilWidth = P3RX_STENCIL_WIDTH_0;
  1121. pSoftP3RX->P3RXLBReadFormat.DepthWidth = P3RX_DEPTH_WIDTH_32;
  1122. pSoftP3RX->P3RXLBWriteFormat.StencilPosition = 0;
  1123. pSoftP3RX->P3RXLBWriteFormat.StencilWidth = P3RX_STENCIL_WIDTH_0;
  1124. pSoftP3RX->P3RXLBWriteFormat.DepthWidth = P3RX_DEPTH_WIDTH_32;
  1125. pSoftP3RX->P3RXDepthMode.Width = P3RX_DEPTH_WIDTH_32;
  1126. pSoftP3RX->P3RXLBWriteMode.ByteEnables = 0xF;
  1127. pSoftP3RX->P3RXLBSourceReadMode.Packed16 = 0;
  1128. pSoftP3RX->P3RXLBDestReadMode.Packed16 = 0;
  1129. pSoftP3RX->P3RXLBWriteMode.Packed16 = 0;
  1130. }
  1131. break;
  1132. }
  1133. }
  1134. else
  1135. // On DX5 we don't look at the pixel format, just the depth of the Z Buffer.
  1136. {
  1137. // Choose the correct Z Buffer depth
  1138. switch(pZBufferInt->pixFmt.dwRGBBitCount)
  1139. {
  1140. default:
  1141. DISPDBG((ERRLVL,"ERROR: Unknown depth format in _D3D_OP_SetRenderTarget!"));
  1142. // Regard the buffer as 16 bit one and fall through
  1143. case 16:
  1144. pSoftP3RX->P3RXLBReadFormat.DepthWidth = __GLINT_DEPTH_WIDTH_16;
  1145. pSoftP3RX->P3RXLBWriteFormat.DepthWidth = __GLINT_DEPTH_WIDTH_16;
  1146. pSoftP3RX->P3RXDepthMode.Width = __GLINT_DEPTH_WIDTH_16;
  1147. pSoftP3RX->P3RXLBWriteMode.ByteEnables = 0x3;
  1148. pSoftP3RX->P3RXLBSourceReadMode.Packed16 = 1;
  1149. pSoftP3RX->P3RXLBDestReadMode.Packed16 = 1;
  1150. pSoftP3RX->P3RXLBWriteMode.Packed16 = 1;
  1151. break;
  1152. case 24:
  1153. pSoftP3RX->P3RXLBReadFormat.DepthWidth = __GLINT_DEPTH_WIDTH_24;
  1154. pSoftP3RX->P3RXLBWriteFormat.DepthWidth = __GLINT_DEPTH_WIDTH_24;
  1155. pSoftP3RX->P3RXDepthMode.Width = __GLINT_DEPTH_WIDTH_24;
  1156. pSoftP3RX->P3RXLBWriteMode.ByteEnables = 0x7;
  1157. pSoftP3RX->P3RXLBSourceReadMode.Packed16 = 0;
  1158. pSoftP3RX->P3RXLBDestReadMode.Packed16 = 0;
  1159. pSoftP3RX->P3RXLBWriteMode.Packed16 = 0;
  1160. break;
  1161. case 32:
  1162. pSoftP3RX->P3RXLBReadFormat.DepthWidth = __GLINT_DEPTH_WIDTH_32;
  1163. pSoftP3RX->P3RXLBWriteFormat.DepthWidth = __GLINT_DEPTH_WIDTH_32;
  1164. pSoftP3RX->P3RXDepthMode.Width = __GLINT_DEPTH_WIDTH_32;
  1165. pSoftP3RX->P3RXLBWriteMode.ByteEnables = 0xF;
  1166. pSoftP3RX->P3RXLBSourceReadMode.Packed16 = 0;
  1167. pSoftP3RX->P3RXLBDestReadMode.Packed16 = 0;
  1168. pSoftP3RX->P3RXLBWriteMode.Packed16 = 0;
  1169. break;
  1170. }
  1171. }
  1172. pSoftP3RX->P3RXLBSourceReadMode.Layout = pZBufferInt->dwPatchMode;
  1173. pSoftP3RX->P3RXLBDestReadMode.Layout = pZBufferInt->dwPatchMode;
  1174. pSoftP3RX->P3RXLBWriteMode.Layout = pZBufferInt->dwPatchMode;
  1175. } // if (pZBufferInt)
  1176. switch (pRenderInt->dwPixelSize)
  1177. {
  1178. case __GLINT_8BITPIXEL:
  1179. // 8 Bit color index mode
  1180. pSoftP3RX->DitherMode.ColorFormat =
  1181. pSoftP3RX->P3RXAlphaBlendColorMode.ColorFormat = P3RX_ALPHABLENDMODE_COLORFORMAT_CI;
  1182. SEND_P3_DATA(PixelSize, 2 - __GLINT_8BITPIXEL);
  1183. break;
  1184. case __GLINT_16BITPIXEL:
  1185. if (pThisDisplay->ddpfDisplay.dwRBitMask == 0x7C00)
  1186. {
  1187. // 5551 format
  1188. pSoftP3RX->DitherMode.ColorFormat = P3RX_DITHERMODE_COLORFORMAT_5551;
  1189. pSoftP3RX->P3RXAlphaBlendColorMode.ColorFormat = P3RX_ALPHABLENDMODE_COLORFORMAT_5551;
  1190. }
  1191. else
  1192. {
  1193. // 565 format
  1194. pSoftP3RX->DitherMode.ColorFormat = P3RX_DITHERMODE_COLORFORMAT_565;
  1195. pSoftP3RX->P3RXAlphaBlendColorMode.ColorFormat = P3RX_ALPHABLENDMODE_COLORFORMAT_565;
  1196. }
  1197. SEND_P3_DATA(PixelSize, 2 - __GLINT_16BITPIXEL);
  1198. break;
  1199. case __GLINT_24BITPIXEL:
  1200. case __GLINT_32BITPIXEL:
  1201. // 32 Bit Color Index mode
  1202. pSoftP3RX->DitherMode.ColorFormat =
  1203. pSoftP3RX->P3RXAlphaBlendColorMode.ColorFormat = P3RX_ALPHABLENDMODE_COLORFORMAT_8888;
  1204. SEND_P3_DATA(PixelSize, 2 - __GLINT_32BITPIXEL);
  1205. break;
  1206. }
  1207. pSoftP3RX->P3RXFBDestReadMode.Layout0 = pRenderInt->dwPatchMode;
  1208. pSoftP3RX->P3RXFBWriteMode.Layout0 = pRenderInt->dwPatchMode;
  1209. pSoftP3RX->P3RXFBSourceReadMode.Layout = pRenderInt->dwPatchMode;
  1210. COPY_P3_DATA(FBWriteMode, pSoftP3RX->P3RXFBWriteMode);
  1211. COPY_P3_DATA(FBDestReadMode, pSoftP3RX->P3RXFBDestReadMode);
  1212. COPY_P3_DATA(FBSourceReadMode, pSoftP3RX->P3RXFBSourceReadMode);
  1213. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  1214. if (!(pContext->Flags & SURFACE_ANTIALIAS) ||
  1215. (pContext->dwAliasBackBuffer == 0))
  1216. {
  1217. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  1218. pContext->PixelOffset = (DWORD)(pRenderInt->fpVidMem -
  1219. pThisDisplay->dwScreenFlatAddr );
  1220. if (pContext->pSurfZBufferInt)
  1221. {
  1222. pContext->ZPixelOffset = (DWORD)(pZBufferInt->fpVidMem -
  1223. pThisDisplay->dwScreenFlatAddr);
  1224. }
  1225. AAMultiplier = 1;
  1226. SEND_P3_DATA(PixelSize, (2 - pRenderInt->dwPixelSize));
  1227. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  1228. }
  1229. else
  1230. {
  1231. pContext->PixelOffset = pContext->dwAliasPixelOffset;
  1232. pContext->ZPixelOffset = pContext->dwAliasZPixelOffset;
  1233. AAMultiplier = 2;
  1234. }
  1235. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  1236. COPY_P3_DATA(AlphaBlendColorMode, pSoftP3RX->P3RXAlphaBlendColorMode);
  1237. COPY_P3_DATA(DitherMode, pSoftP3RX->DitherMode);
  1238. SEND_P3_DATA(FBWriteBufferAddr0, pContext->PixelOffset);
  1239. SEND_P3_DATA(FBDestReadBufferAddr0, pContext->PixelOffset);
  1240. SEND_P3_DATA(FBSourceReadBufferAddr, pContext->PixelOffset);
  1241. SEND_P3_DATA(FBWriteBufferWidth0,
  1242. pContext->pSurfRenderInt->dwPixelPitch * AAMultiplier);
  1243. SEND_P3_DATA(FBDestReadBufferWidth0,
  1244. pContext->pSurfRenderInt->dwPixelPitch * AAMultiplier);
  1245. SEND_P3_DATA(FBSourceReadBufferWidth,
  1246. pContext->pSurfRenderInt->dwPixelPitch * AAMultiplier);
  1247. WAIT_FIFO(20);
  1248. // Is there a Z Buffer?
  1249. if (pContext->pSurfZBufferInt != NULL)
  1250. {
  1251. // Offset is in BYTES
  1252. SEND_P3_DATA(LBSourceReadBufferAddr, pContext->ZPixelOffset);
  1253. SEND_P3_DATA(LBDestReadBufferAddr, pContext->ZPixelOffset);
  1254. SEND_P3_DATA(LBWriteBufferAddr, pContext->ZPixelOffset);
  1255. pSoftP3RX->P3RXLBWriteMode.Width =
  1256. pContext->pSurfZBufferInt->dwPixelPitch * AAMultiplier;
  1257. pSoftP3RX->P3RXLBSourceReadMode.Width =
  1258. pContext->pSurfZBufferInt->dwPixelPitch * AAMultiplier;
  1259. pSoftP3RX->P3RXLBDestReadMode.Width =
  1260. pContext->pSurfZBufferInt->dwPixelPitch * AAMultiplier;
  1261. COPY_P3_DATA(LBDestReadMode, pSoftP3RX->P3RXLBDestReadMode);
  1262. COPY_P3_DATA(LBSourceReadMode, pSoftP3RX->P3RXLBSourceReadMode);
  1263. COPY_P3_DATA(LBWriteMode, pSoftP3RX->P3RXLBWriteMode);
  1264. COPY_P3_DATA(StencilMode, pSoftP3RX->P3RXStencilMode);
  1265. COPY_P3_DATA(LBReadFormat, pSoftP3RX->P3RXLBReadFormat);
  1266. COPY_P3_DATA(LBWriteFormat, pSoftP3RX->P3RXLBWriteFormat);
  1267. COPY_P3_DATA(DepthMode, pSoftP3RX->P3RXDepthMode);
  1268. }
  1269. DIRTY_VIEWPORT(pContext);
  1270. P3_DMA_COMMIT_BUFFER();
  1271. DBG_EXIT(_D3D_OP_SetRenderTarget,0);
  1272. return DD_OK;
  1273. } // _D3D_OP_SetRenderTarget
  1274. //-----------------------------------------------------------------------------
  1275. //
  1276. // _D3D_OP_SceneCapture
  1277. //
  1278. // This function is called twice, once at the start of the rendering,
  1279. // and once at the end of the rendering. The start is ignored, but
  1280. // the end might be used to ensure that the DMA buffer has been flushed.
  1281. // This is needed for the case where a scene has little in it, and
  1282. // doesn't fill the buffer up.
  1283. //
  1284. //-----------------------------------------------------------------------------
  1285. VOID
  1286. _D3D_OP_SceneCapture(
  1287. P3_D3DCONTEXT *pContext,
  1288. DWORD dwFlag)
  1289. {
  1290. P3_THUNKEDDATA *pThisDisplay;
  1291. pThisDisplay = pContext->pThisDisplay;
  1292. if (dwFlag == D3DHAL_SCENE_CAPTURE_START)
  1293. {
  1294. DISPDBG((DBGLVL,"Scene Start"));
  1295. }
  1296. else if (dwFlag == D3DHAL_SCENE_CAPTURE_END)
  1297. {
  1298. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  1299. if (pContext->Flags & SURFACE_ANTIALIAS)
  1300. {
  1301. // Since we were antialiasing we need to put the data where
  1302. // the user asked which requires a copy from our AA buffer
  1303. // into the true target buffer
  1304. // P3 Shrinking is done in the DDRAW context. This means you
  1305. // don't have to save and restore the state around the call
  1306. // - the next D3D_OPERATION will recover for you
  1307. DDRAW_OPERATION(pContext, pThisDisplay);
  1308. P3RX_AA_Shrink(pContext);
  1309. }
  1310. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  1311. DISPDBG((DBGLVL,"Scene End"));
  1312. }
  1313. return;
  1314. } // _D3D_OP_SceneCapture
  1315. #if DX7_TEXMANAGEMENT
  1316. //-----------------------------------------------------------------------------
  1317. //
  1318. // __OP_MarkManagedSurfDirty
  1319. //
  1320. // Make sure textures are setup again if the texture is being used in any of
  1321. // the texture stages (for reloading purpouses) and make sure we mark it as
  1322. // dirty (since we're modifying the sysmem copy of the texture)
  1323. //
  1324. //-----------------------------------------------------------------------------
  1325. VOID __OP_MarkManagedSurfDirty(P3_D3DCONTEXT* pContext,
  1326. DWORD dwSurfHandle,
  1327. P3_SURF_INTERNAL* pTexture)
  1328. {
  1329. // If the destination texture is in use in any of the texture
  1330. // stages, make sure hw gets re-setup again before using it.
  1331. if ((pContext->TextureStageState[0].m_dwVal[D3DTSS_TEXTUREMAP]
  1332. == dwSurfHandle) ||
  1333. (pContext->TextureStageState[1].m_dwVal[D3DTSS_TEXTUREMAP]
  1334. == dwSurfHandle))
  1335. {
  1336. DIRTY_TEXTURE(pContext);
  1337. }
  1338. // Mark the destination texture as needing to be updated
  1339. // into vidmem before using it.
  1340. pTexture->m_bTMNeedUpdate = TRUE;
  1341. } // __OP_MarkManagedSurfDirty
  1342. //-----------------------------------------------------------------------------
  1343. //
  1344. // _D3D_OP_SetTexLod
  1345. //
  1346. // This function processes the D3DDP2OP_SETTEXLOD DP2 command token.
  1347. // This communicates to the texture manager the most detailed mip map level
  1348. // required to load for a given managed surface.
  1349. //
  1350. //-----------------------------------------------------------------------------
  1351. VOID
  1352. _D3D_OP_SetTexLod(
  1353. P3_D3DCONTEXT *pContext,
  1354. D3DHAL_DP2SETTEXLOD* pSetTexLod)
  1355. {
  1356. P3_SURF_INTERNAL* pTexture;
  1357. // Get the source texture structure pointer
  1358. pTexture = GetSurfaceFromHandle(pContext, pSetTexLod->dwDDSurface);
  1359. if (pTexture == NULL)
  1360. {
  1361. return;
  1362. }
  1363. // Set up the HW texture states again if this texture is in use
  1364. // and the new LOD value is smaller than the current setting.
  1365. if (((pContext->TextureStageState[0].m_dwVal[D3DTSS_TEXTUREMAP]
  1366. == pSetTexLod->dwDDSurface) ||
  1367. (pContext->TextureStageState[1].m_dwVal[D3DTSS_TEXTUREMAP]
  1368. == pSetTexLod->dwDDSurface)) &&
  1369. (pSetTexLod->dwLOD < pTexture->m_dwTexLOD))
  1370. {
  1371. DIRTY_TEXTURE(pContext);
  1372. }
  1373. // Change the texture's largest level to be actually used
  1374. pTexture->m_dwTexLOD = pSetTexLod->dwLOD;
  1375. } // _D3D_OP_SetTexLod
  1376. //-----------------------------------------------------------------------------
  1377. //
  1378. // _D3D_OP_SetPriority
  1379. //
  1380. // This function processes the D3DDP2OP_SETPRIORITY DP2 command token.
  1381. //
  1382. //-----------------------------------------------------------------------------
  1383. VOID
  1384. _D3D_OP_SetPriority(
  1385. P3_D3DCONTEXT *pContext,
  1386. D3DHAL_DP2SETPRIORITY* pSetPriority)
  1387. {
  1388. P3_SURF_INTERNAL* pTexture;
  1389. // Get the source texture structure pointer
  1390. #if WNT_DDRAW
  1391. pTexture = GetSurfaceFromHandle(pContext, pSetPriority->dwDDDestSurface);
  1392. #else
  1393. pTexture = GetSurfaceFromHandle(pContext, pSetPriority->dwDDSurface);
  1394. #endif
  1395. if (NULL != pTexture)
  1396. {
  1397. // Managed resources should be evicted depending on their priorities.
  1398. // If of same priority then LRU is used to break the tie.
  1399. pTexture->m_dwPriority = pSetPriority->dwPriority;
  1400. }
  1401. } // _D3D_OP_SetPriority
  1402. #if DX8_DDI
  1403. //-----------------------------------------------------------------------------
  1404. //
  1405. // _D3D_OP_AddDirtyRect
  1406. //
  1407. // This function processes the D3DDP2OP_ADDDIRTYRECT DP2 command token.
  1408. //
  1409. //-----------------------------------------------------------------------------
  1410. VOID
  1411. _D3D_OP_AddDirtyRect(
  1412. P3_D3DCONTEXT *pContext,
  1413. D3DHAL_DP2ADDDIRTYRECT* pAddDirtyRect)
  1414. {
  1415. P3_SURF_INTERNAL* pTexture;
  1416. // Get the source texture structure pointer
  1417. pTexture = GetSurfaceFromHandle(pContext, pAddDirtyRect->dwSurface);
  1418. if (NULL != pTexture)
  1419. {
  1420. //azn TODO
  1421. // As a first implementation in this driver we mark the whole surface
  1422. // as dirty instead of marking just the indicated rect - which could be
  1423. // transferred more efficiently
  1424. __OP_MarkManagedSurfDirty(pContext,
  1425. pAddDirtyRect->dwSurface,
  1426. pTexture);
  1427. }
  1428. } // _D3D_OP_AddDirtyRect
  1429. //-----------------------------------------------------------------------------
  1430. //
  1431. // _D3D_OP_AddDirtyBox
  1432. //
  1433. // This function processes the D3DDP2OP_ADDDIRTYBOX DP2 command token.
  1434. //
  1435. //-----------------------------------------------------------------------------
  1436. VOID
  1437. _D3D_OP_AddDirtyBox(
  1438. P3_D3DCONTEXT *pContext,
  1439. D3DHAL_DP2ADDDIRTYBOX* pAddDirtyBox)
  1440. {
  1441. P3_SURF_INTERNAL* pTexture;
  1442. // Get the source texture structure pointer
  1443. pTexture = GetSurfaceFromHandle(pContext, pAddDirtyBox->dwSurface);
  1444. if (NULL != pTexture)
  1445. {
  1446. //azn TODO
  1447. // As a first implementation in this driver we mark the whole surface
  1448. // as dirty instead of marking just the indicated rect - which could be
  1449. // transferred more efficiently
  1450. __OP_MarkManagedSurfDirty(pContext,
  1451. pAddDirtyBox->dwSurface,
  1452. pTexture);
  1453. }
  1454. } // _D3D_OP_AddDirtyBox
  1455. #endif
  1456. #endif // DX7_TEXMANAGEMENT
  1457. #if DX8_3DTEXTURES
  1458. //-----------------------------------------------------------------------------
  1459. //
  1460. // __OP_BasicVolumeBlt
  1461. //
  1462. // This function blts one single level/slice at a time for volume textures
  1463. //
  1464. //-----------------------------------------------------------------------------
  1465. VOID __OP_BasicVolumeBlt(P3_D3DCONTEXT* pContext,
  1466. P3_THUNKEDDATA*pThisDisplay,
  1467. P3_SURF_INTERNAL* pSrcTexture,
  1468. P3_SURF_INTERNAL* pDestTexture,
  1469. DWORD dwDestSurfHandle,
  1470. RECTL *prSrc,
  1471. RECTL *prDest)
  1472. {
  1473. #if DX7_TEXMANAGEMENT
  1474. if ((0 == (pDestTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)) &&
  1475. (0 == (pSrcTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)) )
  1476. #endif // DX7_TEXMANAGEMENT
  1477. {
  1478. if ((pSrcTexture->Location == SystemMemory) &&
  1479. (pDestTexture->Location == VideoMemory))
  1480. {
  1481. //----------------------------
  1482. // Do the system->videomem blt
  1483. //----------------------------
  1484. _DD_P3Download(pThisDisplay,
  1485. pSrcTexture->fpVidMem,
  1486. pDestTexture->fpVidMem,
  1487. pSrcTexture->dwPatchMode,
  1488. pDestTexture->dwPatchMode,
  1489. pSrcTexture->lPitch,
  1490. pDestTexture->lPitch,
  1491. pDestTexture->dwPixelPitch,
  1492. pDestTexture->dwPixelSize,
  1493. prSrc,
  1494. prDest);
  1495. }
  1496. else
  1497. {
  1498. DISPDBG((ERRLVL, "ERROR: __OP_BasicVolumeBlt b3DTexture (%d -> %d)"
  1499. "not suported yet!",
  1500. pSrcTexture->Location,
  1501. pDestTexture->Location));
  1502. }
  1503. }
  1504. #if DX7_TEXMANAGEMENT
  1505. else if (pSrcTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
  1506. {
  1507. //----------------------------------
  1508. //----------------------------------
  1509. // TEXBLT from a managed texture
  1510. //----------------------------------
  1511. //----------------------------------
  1512. if ((pDestTexture->Location == SystemMemory) ||
  1513. (pDestTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE))
  1514. {
  1515. //-------------------------------------------------
  1516. // Do the Managed surf -> sysmem | managed surf blt
  1517. //-------------------------------------------------
  1518. // make sure we'll reload the vidmem copy of the dest surf
  1519. if (pDestTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
  1520. {
  1521. __OP_MarkManagedSurfDirty(pContext,
  1522. dwDestSurfHandle,
  1523. pDestTexture);
  1524. }
  1525. _DD_BLT_SysMemToSysMemCopy(
  1526. pSrcTexture->fpVidMem,
  1527. pSrcTexture->lPitch,
  1528. pSrcTexture->dwBitDepth,
  1529. pDestTexture->fpVidMem,
  1530. pDestTexture->lPitch,
  1531. pDestTexture->dwBitDepth,
  1532. prSrc,
  1533. prDest);
  1534. }
  1535. else if (pDestTexture->Location == VideoMemory)
  1536. {
  1537. //-------------------------------------------------
  1538. // Do the Managed surf -> vidmem surf blt
  1539. //-------------------------------------------------
  1540. // This might be optimized by doing a vidmem->vidmem
  1541. // when the source managed texture has a vidmem copy
  1542. _DD_P3Download(pThisDisplay,
  1543. pSrcTexture->fpVidMem,
  1544. pDestTexture->fpVidMem,
  1545. pSrcTexture->dwPatchMode,
  1546. pDestTexture->dwPatchMode,
  1547. pSrcTexture->lPitch,
  1548. pDestTexture->lPitch,
  1549. pDestTexture->dwPixelPitch,
  1550. pDestTexture->dwPixelSize,
  1551. prSrc,
  1552. prDest);
  1553. }
  1554. else
  1555. {
  1556. DISPDBG((ERRLVL,"Src-managed __OP_BasicVolumeBlt variation "
  1557. "unimplemented! (from %d into %d)",
  1558. pSrcTexture->Location,
  1559. pDestTexture->Location));
  1560. }
  1561. }
  1562. else if (pDestTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
  1563. {
  1564. //--------------------------------------------------------------
  1565. //--------------------------------------------------------------
  1566. // TEXBLT into a managed texture (except from a managed texture)
  1567. //--------------------------------------------------------------
  1568. //--------------------------------------------------------------
  1569. // managed->managed is handled in the previous case
  1570. if (pSrcTexture->Location == SystemMemory)
  1571. {
  1572. //-------------------------------------------------
  1573. // Do the sysmem surf -> managed surf blt
  1574. //-------------------------------------------------
  1575. // make sure we'll reload the vidmem copy of the dest surf
  1576. __OP_MarkManagedSurfDirty(pContext,
  1577. dwDestSurfHandle,
  1578. pDestTexture);
  1579. _DD_BLT_SysMemToSysMemCopy(
  1580. pSrcTexture->fpVidMem,
  1581. pSrcTexture->lPitch,
  1582. pSrcTexture->dwBitDepth,
  1583. pDestTexture->fpVidMem,
  1584. pDestTexture->lPitch,
  1585. pDestTexture->dwBitDepth,
  1586. prSrc,
  1587. prDest);
  1588. }
  1589. else if (pSrcTexture->Location == VideoMemory)
  1590. {
  1591. //-------------------------------------------------
  1592. // Do the vidmem surf -> Managed surf blt
  1593. //-------------------------------------------------
  1594. if (0 != pSrcTexture->MipLevels[0].fpVidMemTM)
  1595. {
  1596. // Destination is already in vidmem so instead of
  1597. // "dirtying" the managed texture lets do the
  1598. // vidmem->vidmem blt which is faster than doing the
  1599. // update later (in the hope we'll really use it)
  1600. _DD_BLT_P3CopyBlt(pThisDisplay,
  1601. pSrcTexture->fpVidMem,
  1602. pDestTexture->MipLevels[0].fpVidMemTM,
  1603. pSrcTexture->dwPatchMode,
  1604. pDestTexture->dwPatchMode,
  1605. pSrcTexture->dwPixelPitch,
  1606. pDestTexture->dwPixelPitch,
  1607. pSrcTexture->MipLevels[0].dwOffsetFromMemoryBase,
  1608. pDestTexture->MipLevels[0].dwOffsetFromMemoryBase,
  1609. pDestTexture->dwPixelSize,
  1610. prSrc,
  1611. prDest);
  1612. }
  1613. else
  1614. {
  1615. // make sure we'll reload the
  1616. // vidmem copy of the dest surf
  1617. __OP_MarkManagedSurfDirty(pContext,
  1618. dwDestSurfHandle,
  1619. pDestTexture);
  1620. }
  1621. // Do slow mem mapped framebuffer blt into sysmem
  1622. // The source surface lives in video mem so we need to get a
  1623. // "real" sysmem address for it:
  1624. _DD_BLT_SysMemToSysMemCopy(
  1625. D3DSURF_GETPOINTER(pSrcTexture, pThisDisplay),
  1626. pSrcTexture->lPitch,
  1627. pSrcTexture->dwBitDepth,
  1628. pDestTexture->fpVidMem,
  1629. pDestTexture->lPitch,
  1630. pDestTexture->dwBitDepth,
  1631. prSrc,
  1632. prDest);
  1633. }
  1634. else if (pSrcTexture->Location == AGPMemory)
  1635. {
  1636. // make sure we'll reload the vidmem copy of the dest surf
  1637. __OP_MarkManagedSurfDirty(pContext,
  1638. dwDestSurfHandle,
  1639. pDestTexture);
  1640. _DD_BLT_SysMemToSysMemCopy(
  1641. pSrcTexture->fpVidMem,
  1642. pSrcTexture->lPitch,
  1643. pSrcTexture->dwBitDepth,
  1644. pDestTexture->fpVidMem,
  1645. pDestTexture->lPitch,
  1646. pDestTexture->dwBitDepth,
  1647. prSrc,
  1648. prDest);
  1649. }
  1650. else
  1651. {
  1652. DISPDBG((ERRLVL,"Dest-managed __OP_BasicVolumeBlt variation "
  1653. "unimplemented! (from %d into %d)",
  1654. pSrcTexture->Location,
  1655. pDestTexture->Location));
  1656. }
  1657. }
  1658. else
  1659. {
  1660. DISPDBG((ERRLVL,"__OP_BasicVolumeBlt variation unimplemented! "
  1661. "(from %d into %d)",
  1662. pSrcTexture->Location,
  1663. pDestTexture->Location));
  1664. }
  1665. #endif // DX7_TEXMANAGEMENT
  1666. } // __OP_BasicVolumeBlt
  1667. //-----------------------------------------------------------------------------
  1668. //
  1669. // _D3D_OP_VolumeBlt
  1670. //
  1671. // This function processes the D3DDP2OP_VOLUMEBLT DP2 command token.
  1672. //
  1673. //-----------------------------------------------------------------------------
  1674. VOID _D3D_OP_VolumeBlt(P3_D3DCONTEXT* pContext,
  1675. P3_THUNKEDDATA*pThisDisplay,
  1676. D3DHAL_DP2VOLUMEBLT* pBlt)
  1677. {
  1678. LPDDRAWI_DDRAWSURFACE_LCL pSrcLcl;
  1679. LPDDRAWI_DDRAWSURFACE_LCL pDestLcl;
  1680. P3_SURF_INTERNAL* pSrcTexture;
  1681. P3_SURF_INTERNAL* pDestTexture;
  1682. P3_SURF_FORMAT* pFormatSource;
  1683. P3_SURF_FORMAT* pFormatDest;
  1684. RECTL rSrc, rDest;
  1685. DWORD dwSrcCurrDepth, dwDestCurrDepth, dwEndDepth;
  1686. // Get the texture structure pointers
  1687. pSrcTexture = GetSurfaceFromHandle(pContext, pBlt->dwDDSrcSurface);
  1688. pDestTexture = GetSurfaceFromHandle(pContext, pBlt->dwDDDestSurface);
  1689. // Check that the textures are valid
  1690. if (pSrcTexture == NULL)
  1691. {
  1692. DISPDBG((ERRLVL, "ERROR: Source texture %d is invalid!",
  1693. pBlt->dwDDSrcSurface));
  1694. return;
  1695. }
  1696. if (pDestTexture == NULL)
  1697. {
  1698. DISPDBG((ERRLVL, "ERROR: Dest texture %d is invalid!",
  1699. pBlt->dwDDDestSurface));
  1700. return;
  1701. }
  1702. // If we are going to blt 3D texture, both have to be 3D texture
  1703. if ((pSrcTexture->b3DTexture == FALSE) != (pDestTexture->b3DTexture == FALSE))
  1704. {
  1705. DISPDBG((ERRLVL, "ERROR: TEXBLT b3DTexture (%d %d)does not match!",
  1706. pSrcTexture->b3DTexture,
  1707. pDestTexture->b3DTexture));
  1708. return;
  1709. }
  1710. // Do we blt whole 3D texture ?
  1711. if ((pBlt->srcBox.Left == 0) &&
  1712. (pBlt->srcBox.Top == 0) &&
  1713. (pBlt->srcBox.Right == pSrcTexture->wWidth) &&
  1714. (pBlt->srcBox.Bottom == pSrcTexture->wHeight) &&
  1715. (pBlt->srcBox.Front == 0) &&
  1716. (pBlt->srcBox.Back == pSrcTexture->wDepth) &&
  1717. (pBlt->dwDestX == 0) &&
  1718. (pBlt->dwDestY == 0) &&
  1719. (pBlt->dwDestZ == 0) &&
  1720. (pSrcTexture->wWidth == pDestTexture->wWidth) &&
  1721. (pSrcTexture->wHeight == pDestTexture->wHeight) &&
  1722. (pSrcTexture->wDepth == pDestTexture->wDepth))
  1723. {
  1724. // Build source rectangle
  1725. rSrc.left = 0;
  1726. rSrc.top = 0;
  1727. rSrc.right = pBlt->srcBox.Right;
  1728. rSrc.bottom = pBlt->srcBox.Bottom * pBlt->srcBox.Back;
  1729. // Destination rectangle is same as source.
  1730. rDest = rSrc;
  1731. // Switch to the DirectDraw context
  1732. DDRAW_OPERATION(pContext, pThisDisplay);
  1733. // Do the Blt!
  1734. __OP_BasicVolumeBlt(pContext,
  1735. pThisDisplay,
  1736. pSrcTexture,
  1737. pDestTexture,
  1738. pBlt->dwDDDestSurface,
  1739. &rSrc,
  1740. &rDest);
  1741. // Switch back to the Direct3D context
  1742. D3D_OPERATION(pContext, pThisDisplay);
  1743. return;
  1744. }
  1745. // Build source rectangle.
  1746. rSrc.left = pBlt->srcBox.Left;
  1747. rSrc.top = pBlt->srcBox.Top;
  1748. rSrc.right = pBlt->srcBox.Right;
  1749. rSrc.bottom = pBlt->srcBox.Bottom;
  1750. // Build destination rectangle.
  1751. rDest.left = pBlt->dwDestX;
  1752. rDest.top = pBlt->dwDestY;
  1753. rDest.right = pBlt->dwDestX + (rSrc.right - rSrc.left);
  1754. rDest.bottom = pBlt->dwDestY + (rSrc.bottom - rSrc.top);
  1755. // Adjust rectangle if blt from non-1st slice.
  1756. if (pBlt->srcBox.Front)
  1757. {
  1758. ULONG ulOffset = pSrcTexture->wDepth * pBlt->srcBox.Front;
  1759. rSrc.top += ulOffset;
  1760. rSrc.bottom += ulOffset;
  1761. }
  1762. // Adjust rectangle if blt to non-1st slice.
  1763. if (pBlt->dwDestZ)
  1764. {
  1765. ULONG ulOffset = pDestTexture->wDepth * pBlt->dwDestZ;
  1766. rDest.top += ulOffset;
  1767. rDest.bottom += ulOffset;
  1768. }
  1769. dwSrcCurrDepth = pBlt->srcBox.Front;
  1770. dwDestCurrDepth = pBlt->dwDestZ;
  1771. dwEndDepth = min(pBlt->dwDestZ + (pBlt->srcBox.Back - pBlt->srcBox.Front),
  1772. pDestTexture->wDepth);
  1773. dwEndDepth = min(dwEndDepth, pSrcTexture->wDepth);
  1774. while(dwDestCurrDepth < dwEndDepth)
  1775. {
  1776. // Switch to the DirectDraw context
  1777. DDRAW_OPERATION(pContext, pThisDisplay);
  1778. // Do the Blt!
  1779. __OP_BasicVolumeBlt(pContext,
  1780. pThisDisplay,
  1781. pSrcTexture,
  1782. pDestTexture,
  1783. pBlt->dwDDDestSurface,
  1784. &rSrc,
  1785. &rDest);
  1786. // Switch back to the Direct3D context
  1787. D3D_OPERATION(pContext, pThisDisplay);
  1788. // Move the source and destination rect to next slice.
  1789. rSrc.top += pSrcTexture->wDepth;
  1790. rSrc.bottom += pSrcTexture->wDepth;
  1791. rDest.top += pDestTexture->wDepth;
  1792. rDest.bottom += pDestTexture->wDepth;
  1793. // Move on to next slice.
  1794. dwSrcCurrDepth++;
  1795. dwDestCurrDepth++;
  1796. }
  1797. } // _D3D_OP_VolumeBlt
  1798. #endif // DX8_3DTEXTURES
  1799. #if DX8_DDI
  1800. //-----------------------------------------------------------------------------
  1801. //
  1802. // _D3D_OP_BufferBlt
  1803. //
  1804. // This function processes the D3DDP2OP_BUFFERBLT DP2 command token.
  1805. //
  1806. //-----------------------------------------------------------------------------
  1807. VOID _D3D_OP_BufferBlt(P3_D3DCONTEXT* pContext,
  1808. P3_THUNKEDDATA*pThisDisplay,
  1809. D3DHAL_DP2BUFFERBLT* pBlt)
  1810. {
  1811. #if DX7_VERTEXBUFFERS
  1812. // This command token is only sent to drivers
  1813. // supporting videomemory vertexbuffers. That is
  1814. // why we won't see it come down to this driver.
  1815. #endif DX7_VERTEXBUFFERS
  1816. } // _D3D_OP_BufferBlt
  1817. #endif // DX8_DDI
  1818. #if DX8_VERTEXSHADERS
  1819. //-----------------------------------------------------------------------------
  1820. //
  1821. // _D3D_OP_VertexShader_Create
  1822. //
  1823. // This function processes the D3DDP2OP_CREATEVERTEXSHADER DP2 command token.
  1824. //
  1825. //-----------------------------------------------------------------------------
  1826. HRESULT
  1827. _D3D_OP_VertexShader_Create(
  1828. P3_D3DCONTEXT* pContext,
  1829. DWORD dwVtxShaderHandle,
  1830. DWORD dwDeclSize,
  1831. DWORD dwCodeSize,
  1832. BYTE *pShader)
  1833. {
  1834. // Here we would use the data passed by the vertex shader
  1835. // creation block in order to instantiate or compile the
  1836. // given vertex shader. Since this hardware can't support
  1837. // vertex shaders at this time, we just skip the data.
  1838. return DD_OK;
  1839. } // _D3D_OP_VertexShader_Create
  1840. //-----------------------------------------------------------------------------
  1841. //
  1842. // _D3D_OP_VertexShader_Delete
  1843. //
  1844. // This function processes the D3DDP2OP_DELETEVERTEXSHADER DP2 command token.
  1845. //
  1846. //-----------------------------------------------------------------------------
  1847. VOID
  1848. _D3D_OP_VertexShader_Delete(
  1849. P3_D3DCONTEXT* pContext,
  1850. DWORD dwVtxShaderHandle)
  1851. {
  1852. // Here we would use the data passed by the vertex shader
  1853. // delete block in order to destroy the given vertex shader.
  1854. // Since this hardware can't support vertex shaders at
  1855. // this time, we just skip the data.
  1856. } // _D3D_OP_VertexShader_Delete
  1857. #define RDVSD_ISLEGACY(ShaderHandle) !(ShaderHandle & D3DFVF_RESERVED0)
  1858. //-----------------------------------------------------------------------------
  1859. //
  1860. // _D3D_OP_VertexShader_Set
  1861. //
  1862. // This function processes the D3DDP2OP_SETVERTEXSHADER DP2 command token.
  1863. //
  1864. //-----------------------------------------------------------------------------
  1865. VOID
  1866. _D3D_OP_VertexShader_Set(
  1867. P3_D3DCONTEXT* pContext,
  1868. DWORD dwVtxShaderHandle)
  1869. {
  1870. // Here we would use the data passed by the vertex shader
  1871. // set block in order to setup the given vertex shader.
  1872. // Since this hardware can't support vertex shaders at
  1873. // this time, we usually just skip the data. However under
  1874. // the circumstances described below, we might be passed a
  1875. // FVF vertex format
  1876. DISPDBG((DBGLVL,"Setting up shader # 0x%x",dwVtxShaderHandle));
  1877. #if DX7_D3DSTATEBLOCKS
  1878. if ( pContext->bStateRecMode )
  1879. {
  1880. _D3D_SB_Record_VertexShader_Set(pContext, dwVtxShaderHandle);
  1881. return;
  1882. }
  1883. #endif // DX7_D3DSTATEBLOCKS
  1884. // Zero is a special handle that tells the driver to
  1885. // invalidate the currently set shader.
  1886. if( dwVtxShaderHandle == 0 )
  1887. {
  1888. DISPDBG((WRNLVL,"Invalidating the currently set shader"));
  1889. return ;
  1890. }
  1891. if( RDVSD_ISLEGACY(dwVtxShaderHandle) )
  1892. {
  1893. // Make it parse the FVF
  1894. pContext->dwVertexType = dwVtxShaderHandle;
  1895. }
  1896. else
  1897. {
  1898. DISPDBG((ERRLVL,"_D3D_OP_VertexShader_Set: Illegal shader handle "
  1899. "(This driver cant do vertex processing)"));
  1900. }
  1901. } // _D3D_OP_VertexShader_Set
  1902. //-----------------------------------------------------------------------------
  1903. //
  1904. // _D3D_OP_VertexShader_SetConst
  1905. //
  1906. // This function processes the D3DDP2OP_SETVERTEXSHADERCONST DP2 command token.
  1907. //
  1908. //-----------------------------------------------------------------------------
  1909. VOID
  1910. _D3D_OP_VertexShader_SetConst(
  1911. P3_D3DCONTEXT* pContext,
  1912. DWORD dwRegister,
  1913. DWORD dwConst,
  1914. DWORD *pdwValues)
  1915. {
  1916. // Here we would use the data passed by the vertex shader
  1917. // constant block in order to set up the constant entry.
  1918. // Since this hardware can't support vertex shaders at
  1919. // this time, we just skip the data.
  1920. } // _D3D_OP_VertexShader_SetConst
  1921. #endif // DX8_VERTEXSHADERS
  1922. #if DX8_PIXELSHADERS
  1923. //-----------------------------------------------------------------------------
  1924. //
  1925. // _D3D_OP_PixelShader_Create
  1926. //
  1927. // This function processes the D3DDP2OP_CREATEPIXELSHADER DP2 command token.
  1928. //
  1929. //-----------------------------------------------------------------------------
  1930. HRESULT
  1931. _D3D_OP_PixelShader_Create(
  1932. P3_D3DCONTEXT* pContext,
  1933. DWORD dwPxlShaderHandle,
  1934. DWORD dwCodeSize,
  1935. BYTE *pShader)
  1936. {
  1937. // Here we would use the data passed by the pixel shader
  1938. // creation block in order to instantiate or compile the
  1939. // given pixel shader.
  1940. // Since this hardware can't support pixel shaders at this
  1941. // time, we fail the call in case we're called to create a
  1942. // 255.255 version shader!
  1943. return D3DERR_DRIVERINVALIDCALL;
  1944. } // _D3D_OP_PixelShader_Create
  1945. //-----------------------------------------------------------------------------
  1946. //
  1947. // _D3D_OP_PixelShader_Delete
  1948. //
  1949. // This function processes the D3DDP2OP_DELETEPIXELSHADER DP2 command token.
  1950. //
  1951. //-----------------------------------------------------------------------------
  1952. VOID
  1953. _D3D_OP_PixelShader_Delete(
  1954. P3_D3DCONTEXT* pContext,
  1955. DWORD dwPxlShaderHandle)
  1956. {
  1957. // Here we would use the data passed by the pixel shader
  1958. // delete block in order to destroy the given pixel shader.
  1959. // Since this hardware can't support pixel shaders at
  1960. // this time, we just skip the data.
  1961. } // _D3D_OP_PixelShader_Delete
  1962. //-----------------------------------------------------------------------------
  1963. //
  1964. // _D3D_OP_PixelShader_Set
  1965. //
  1966. // This function processes the D3DDP2OP_SETPIXELSHADER DP2 command token.
  1967. //
  1968. //-----------------------------------------------------------------------------
  1969. VOID
  1970. _D3D_OP_PixelShader_Set(
  1971. P3_D3DCONTEXT* pContext,
  1972. DWORD dwPxlShaderHandle)
  1973. {
  1974. // Here we would use the data passed by the pixel shader
  1975. // set block in order to setup the given pixel shader.
  1976. // Since this hardware can't support pixel shaders at
  1977. // this time, we just skip the data.
  1978. } // _D3D_OP_PixelShader_Set
  1979. //-----------------------------------------------------------------------------
  1980. //
  1981. // _D3D_OP_PixelShader_SetConst
  1982. //
  1983. // This function processes the D3DDP2OP_SETPIXELSHADERCONST DP2 command token.
  1984. //
  1985. //-----------------------------------------------------------------------------
  1986. VOID
  1987. _D3D_OP_PixelShader_SetConst(
  1988. P3_D3DCONTEXT* pContext,
  1989. DWORD dwRegister,
  1990. DWORD dwCount,
  1991. DWORD *pdwValues)
  1992. {
  1993. // Here we would use the data passed by the pixel shader
  1994. // set block in order to setup the given pixel shader constants.
  1995. // Since this hardware can't support pixel shaders at
  1996. // this time, we just skip the data.
  1997. } // _D3D_OP_PixelShader_SetConst
  1998. #endif // DX8_PIXELSHADERS
  1999. #if DX8_MULTSTREAMS
  2000. //-----------------------------------------------------------------------------
  2001. //
  2002. // _D3D_OP_MStream_SetSrc
  2003. //
  2004. // This function processes the D3DDP2OP_SETSTREAMSOURCE DP2 command token.
  2005. //
  2006. //-----------------------------------------------------------------------------
  2007. VOID
  2008. _D3D_OP_MStream_SetSrc(
  2009. P3_D3DCONTEXT* pContext,
  2010. DWORD dwStream,
  2011. DWORD dwVBHandle,
  2012. DWORD dwStride)
  2013. {
  2014. P3_SURF_INTERNAL *pSrcStream;
  2015. DBG_ENTRY(_D3D_OP_MStream_SetSrc);
  2016. #if DX7_D3DSTATEBLOCKS
  2017. if ( pContext->bStateRecMode )
  2018. {
  2019. _D3D_SB_Record_MStream_SetSrc(pContext, dwStream, dwVBHandle, dwStride);
  2020. return;
  2021. }
  2022. #endif // DX7_D3DSTATEBLOCKS
  2023. if (dwVBHandle != 0)
  2024. {
  2025. if (dwStream == 0)
  2026. {
  2027. // Get the surface structure pointers for stream #0
  2028. pSrcStream = GetSurfaceFromHandle(pContext, dwVBHandle);
  2029. if (pSrcStream)
  2030. {
  2031. DISPDBG((DBGLVL,"Address of VB = 0x%x "
  2032. "dwVBHandle = %d , dwStride = %d",
  2033. pSrcStream->fpVidMem,dwVBHandle, dwStride));
  2034. pContext->lpVertices = (LPDWORD)pSrcStream->fpVidMem;
  2035. pContext->dwVerticesStride = dwStride;
  2036. if (dwStride > 0)
  2037. {
  2038. // DX8 has mixed types of vertices in one VB, size in bytes
  2039. // of the vertex buffer must be preserved
  2040. pContext->dwVBSizeInBytes = pSrcStream->lPitch;
  2041. // for VBs the wHeight should always be == 1.
  2042. // dwNumVertices stores the # of vertices in the VB
  2043. // On Win2K, both wWidth and lPitch are the buffer size
  2044. // On Win9x, only lPitch is the buffer size, wWidth is 0
  2045. // The same fact is also true for the index buffer
  2046. pContext->dwNumVertices = pSrcStream->lPitch / dwStride;
  2047. DISPDBG((DBGLVL,"dwVBHandle pContext->dwNumVertices = "
  2048. "pSrcStream->lPitch / dwStride = %d %d %d %d",
  2049. dwVBHandle,
  2050. pContext->dwNumVertices,
  2051. pSrcStream->lPitch,dwStride));
  2052. #if DX7_D3DSTATEBLOCKS
  2053. pContext->dwVBHandle = dwVBHandle;
  2054. #endif // DX7_D3DSTATEBLOCKS
  2055. }
  2056. else
  2057. {
  2058. pContext->dwVBSizeInBytes = 0;
  2059. pContext->dwNumVertices = 0;
  2060. DISPDBG((ERRLVL,"INVALID Stride is 0. VB Size undefined"));
  2061. }
  2062. }
  2063. else
  2064. {
  2065. DISPDBG((ERRLVL,"ERROR Address of VB is NULL, "
  2066. "dwStream = %d dwVBHandle = %d , dwStride = %d",
  2067. dwStream, dwVBHandle, dwStride));
  2068. }
  2069. }
  2070. else
  2071. {
  2072. DISPDBG((WRNLVL,"We don't handle other streams than #0"));
  2073. }
  2074. }
  2075. else
  2076. {
  2077. // We are unsetting the stream
  2078. pContext->lpVertices = NULL;
  2079. DISPDBG((WRNLVL,"Unsetting a stream: "
  2080. "dwStream = %d dwVBHandle = %d , dwStride = %d",
  2081. dwStream, dwVBHandle, dwStride));
  2082. }
  2083. DBG_EXIT(_D3D_OP_MStream_SetSrc, 0);
  2084. } // _D3D_OP_MStream_SetSrc
  2085. //-----------------------------------------------------------------------------
  2086. //
  2087. // _D3D_OP_MStream_SetSrcUM
  2088. //
  2089. // This function processes the D3DDP2OP_SETSTREAMSOURCEUM DP2 command token.
  2090. //
  2091. //-----------------------------------------------------------------------------
  2092. VOID
  2093. _D3D_OP_MStream_SetSrcUM(
  2094. P3_D3DCONTEXT* pContext,
  2095. DWORD dwStream,
  2096. DWORD dwStride,
  2097. LPBYTE pUMVtx,
  2098. DWORD dwVBSize)
  2099. {
  2100. DBG_ENTRY(_D3D_OP_MStream_SetSrcUM);
  2101. if (dwStream == 0)
  2102. {
  2103. // Set the stream # 0 information
  2104. DISPDBG((DBGLVL,"_D3D_OP_MStream_SetSrcUM: "
  2105. "Setting VB@ 0x%x dwstride=%d", pUMVtx, dwStride));
  2106. pContext->lpVertices = (LPDWORD)pUMVtx;
  2107. pContext->dwVerticesStride = dwStride;
  2108. pContext->dwVBSizeInBytes = dwVBSize * dwStride;
  2109. pContext->dwNumVertices = dwVBSize ; // comes from the DP2 data
  2110. // structure
  2111. }
  2112. else
  2113. {
  2114. DISPDBG((WRNLVL,"_D3D_OP_MStream_SetSrcUM: "
  2115. "We don't handle other streams than #0"));
  2116. }
  2117. DBG_EXIT(_D3D_OP_MStream_SetSrcUM, 0);
  2118. } // _D3D_OP_MStream_SetSrcUM
  2119. //-----------------------------------------------------------------------------
  2120. //
  2121. // _D3D_OP_MStream_SetIndices
  2122. //
  2123. // This function processes the D3DDP2OP_SETINDICES DP2 command token.
  2124. //
  2125. //-----------------------------------------------------------------------------
  2126. VOID
  2127. _D3D_OP_MStream_SetIndices(
  2128. P3_D3DCONTEXT* pContext,
  2129. DWORD dwVBHandle,
  2130. DWORD dwStride)
  2131. {
  2132. P3_SURF_INTERNAL *pIndxStream;
  2133. DBG_ENTRY(_D3D_OP_MStream_SetIndices);
  2134. #if DX7_D3DSTATEBLOCKS
  2135. if ( pContext->bStateRecMode )
  2136. {
  2137. _D3D_SB_Record_MStream_SetIndices(pContext, dwVBHandle, dwStride);
  2138. return;
  2139. }
  2140. #endif // DX7_D3DSTATEBLOCKS
  2141. // NULL dwVBHandle just means that the Index should be unset
  2142. if (dwVBHandle != 0)
  2143. {
  2144. // Get the indices surface structure pointer
  2145. pIndxStream = GetSurfaceFromHandle(pContext, dwVBHandle);
  2146. if (pIndxStream)
  2147. {
  2148. DISPDBG((DBGLVL,"Address of VB = 0x%x", pIndxStream->fpVidMem));
  2149. pContext->lpIndices = (LPDWORD)pIndxStream->fpVidMem;
  2150. pContext->dwIndicesStride = dwStride; // 2 or 4 for 16/32bit indices
  2151. #if DX7_D3DSTATEBLOCKS
  2152. pContext->dwIndexHandle = dwVBHandle; // Index buffer handle
  2153. #endif
  2154. }
  2155. else
  2156. {
  2157. DISPDBG((ERRLVL,"ERROR Address of Index Surface is NULL, "
  2158. "dwVBHandle = %d , dwStride = %d",
  2159. dwVBHandle, dwStride));
  2160. }
  2161. }
  2162. else
  2163. {
  2164. // We are unsetting the stream
  2165. pContext->lpIndices = NULL;
  2166. DISPDBG((WRNLVL,"Unsetting an index stream: "
  2167. "dwVBHandle = %d , dwStride = %d",
  2168. dwVBHandle, dwStride));
  2169. }
  2170. DBG_EXIT(_D3D_OP_MStream_SetIndices, 0);
  2171. } // _D3D_OP_MStream_SetIndices
  2172. //-----------------------------------------------------------------------------
  2173. //
  2174. // _D3D_OP_MStream_DrawPrim
  2175. //
  2176. // This function processes the D3DDP2OP_DRAWPRIMITIVE DP2 command token.
  2177. //
  2178. //-----------------------------------------------------------------------------
  2179. VOID
  2180. _D3D_OP_MStream_DrawPrim(
  2181. P3_D3DCONTEXT* pContext,
  2182. D3DPRIMITIVETYPE primType,
  2183. DWORD VStart,
  2184. DWORD PrimitiveCount)
  2185. {
  2186. DBG_ENTRY(_D3D_OP_MStream_DrawPrim);
  2187. DISPDBG((DBGLVL,"_D3D_OP_MStream_DrawPrim "
  2188. "primType=0x%x VStart=%d PrimitiveCount=%d",
  2189. primType, VStart, PrimitiveCount));
  2190. _D3D_OP_MStream_DrawPrim2(pContext,
  2191. primType,
  2192. VStart * pContext->FVFData.dwStride,
  2193. PrimitiveCount);
  2194. DBG_EXIT(_D3D_OP_MStream_DrawPrim, 0);
  2195. } // _D3D_OP_MStream_DrawPrim
  2196. //-----------------------------------------------------------------------------
  2197. //
  2198. // _D3D_OP_MStream_DrawIndxP
  2199. //
  2200. // This function processes the D3DDP2OP_DRAWINDEXEDPRIMITIVE DP2 command token.
  2201. //
  2202. //-----------------------------------------------------------------------------
  2203. VOID
  2204. _D3D_OP_MStream_DrawIndxP(
  2205. P3_D3DCONTEXT* pContext,
  2206. D3DPRIMITIVETYPE primType,
  2207. DWORD BaseVertexIndex,
  2208. DWORD MinIndex,
  2209. DWORD NumVertices,
  2210. DWORD StartIndex,
  2211. DWORD PrimitiveCount)
  2212. {
  2213. DBG_ENTRY(_D3D_OP_MStream_DrawIndxP);
  2214. DISPDBG((DBGLVL,"_D3D_OP_MStream_DrawIndxP "
  2215. "primType=0x%x BaseVertexIndex=%d MinIndex=%d"
  2216. "NumVertices =%d StartIndex=%d PrimitiveCount=%d",
  2217. primType, BaseVertexIndex, MinIndex,
  2218. NumVertices, StartIndex, PrimitiveCount));
  2219. _D3D_OP_MStream_DrawIndxP2(pContext,
  2220. primType,
  2221. BaseVertexIndex * pContext->FVFData.dwStride,
  2222. MinIndex,
  2223. NumVertices,
  2224. StartIndex * pContext->dwIndicesStride,
  2225. PrimitiveCount);
  2226. DBG_EXIT(_D3D_OP_MStream_DrawIndxP, 0);
  2227. } // _D3D_OP_MStream_DrawIndxP
  2228. //-----------------------------------------------------------------------------
  2229. //
  2230. // Validate the context settings to use the current streams
  2231. //
  2232. //-----------------------------------------------------------------------------
  2233. BOOL
  2234. __OP_ValidateStreams(
  2235. P3_D3DCONTEXT* pContext,
  2236. BOOL bCheckIndexStream)
  2237. {
  2238. if ((pContext->dwVerticesStride == 0) ||
  2239. (pContext->FVFData.dwStride == 0))
  2240. {
  2241. DISPDBG((ERRLVL,"The zero'th stream is doesn't have a valid VB set"));
  2242. return FALSE;
  2243. }
  2244. if (pContext->dwVerticesStride < pContext->FVFData.dwStride)
  2245. {
  2246. DISPDBG((ERRLVL,"The stride set for the vertex stream is "
  2247. "less than the FVF vertex size"));
  2248. return FALSE;
  2249. }
  2250. //@@BEGIN_DDKSPLIT
  2251. // This shouldn't happen, but lets watch for it since it would show
  2252. // up as weird mangled & distorted triangles
  2253. if (pContext->dwVerticesStride != pContext->FVFData.dwStride)
  2254. {
  2255. DISPDBG((ERRLVL,"Strides(indx-prim) <> %d %d ",
  2256. pContext->dwVerticesStride,pContext->FVFData.dwStride));
  2257. }
  2258. //@@END_DDKSPLIT
  2259. if ((bCheckIndexStream) && (NULL == pContext->lpIndices))
  2260. {
  2261. DISPDBG((ERRLVL,"Pointer to index buffer is null"));
  2262. return FALSE;
  2263. }
  2264. if (NULL == pContext->lpVertices)
  2265. {
  2266. DISPDBG((ERRLVL,"Pointer to vertex buffer is null"));
  2267. return FALSE;
  2268. }
  2269. return TRUE;
  2270. } // __OP_ValidateStreams
  2271. //-----------------------------------------------------------------------------
  2272. //
  2273. // _D3D_OP_MStream_DrawPrim2
  2274. //
  2275. // This function processes the D3DDP2OP_DRAWPRIMITIVE2 DP2 command token.
  2276. //
  2277. //-----------------------------------------------------------------------------
  2278. VOID
  2279. _D3D_OP_MStream_DrawPrim2(
  2280. P3_D3DCONTEXT* pContext,
  2281. D3DPRIMITIVETYPE primType,
  2282. DWORD FirstVertexOffset,
  2283. DWORD PrimitiveCount)
  2284. {
  2285. BOOL bError;
  2286. WORD wVStart;
  2287. DWORD dwFillMode = pContext->RenderStates[D3DRENDERSTATE_FILLMODE];
  2288. LPBYTE lpVertices;
  2289. DWORD dwNumVertices;
  2290. DBG_ENTRY(_D3D_OP_MStream_DrawPrim2);
  2291. DISPDBG((DBGLVL ,"_D3D_OP_MStream_DrawPrim2 "
  2292. "primType=0x%x FirstVertexOffset=%d PrimitiveCount=%d",
  2293. primType, FirstVertexOffset, PrimitiveCount));
  2294. if (!__OP_ValidateStreams(pContext, FALSE))
  2295. {
  2296. return;
  2297. }
  2298. // Watchout: Sometimes (particularly when CLIPPEDTRIFAN are drawn),
  2299. // FirstVertexOffset might not be divided evenly by the dwStride
  2300. lpVertices = ((LPBYTE)pContext->lpVertices) + FirstVertexOffset;
  2301. dwNumVertices = pContext->dwVBSizeInBytes - FirstVertexOffset;
  2302. dwNumVertices /= pContext->dwVerticesStride;
  2303. wVStart = 0;
  2304. switch(primType)
  2305. {
  2306. case D3DPT_POINTLIST:
  2307. {
  2308. D3DHAL_DP2POINTS dp2Points;
  2309. dp2Points.wVStart = wVStart;
  2310. #if DX8_POINTSPRITES
  2311. if(IS_POINTSPRITE_ACTIVE(pContext))
  2312. {
  2313. _D3D_R3_DP2_PointsSprite_DWCount(pContext,
  2314. PrimitiveCount,
  2315. (LPBYTE)&dp2Points,
  2316. (LPD3DTLVERTEX)lpVertices,
  2317. dwNumVertices,
  2318. &bError);
  2319. }
  2320. else
  2321. #endif // DX8_POINTSPRITES
  2322. {
  2323. _D3D_R3_DP2_Points_DWCount(pContext,
  2324. PrimitiveCount,
  2325. (LPBYTE)&dp2Points,
  2326. (LPD3DTLVERTEX)lpVertices,
  2327. dwNumVertices,
  2328. &bError);
  2329. }
  2330. }
  2331. break;
  2332. case D3DPT_LINELIST:
  2333. _D3D_R3_DP2_LineList(pContext,
  2334. PrimitiveCount,
  2335. (LPBYTE)&wVStart,
  2336. (LPD3DTLVERTEX)lpVertices,
  2337. dwNumVertices,
  2338. &bError);
  2339. break;
  2340. case D3DPT_LINESTRIP:
  2341. _D3D_R3_DP2_LineStrip(pContext,
  2342. PrimitiveCount,
  2343. (LPBYTE)&wVStart,
  2344. (LPD3DTLVERTEX)lpVertices,
  2345. dwNumVertices,
  2346. &bError);
  2347. break;
  2348. case D3DPT_TRIANGLELIST:
  2349. _D3D_R3_DP2_TriangleList(pContext,
  2350. PrimitiveCount,
  2351. (LPBYTE)&wVStart,
  2352. (LPD3DTLVERTEX)lpVertices,
  2353. dwNumVertices,
  2354. &bError);
  2355. break;
  2356. case D3DPT_TRIANGLESTRIP:
  2357. _D3D_R3_DP2_TriangleStrip(pContext,
  2358. PrimitiveCount,
  2359. (LPBYTE)&wVStart,
  2360. (LPD3DTLVERTEX)lpVertices,
  2361. dwNumVertices,
  2362. &bError);
  2363. break;
  2364. case D3DPT_TRIANGLEFAN:
  2365. _D3D_R3_DP2_TriangleFan(pContext,
  2366. PrimitiveCount,
  2367. (LPBYTE)&wVStart,
  2368. (LPD3DTLVERTEX)lpVertices,
  2369. dwNumVertices,
  2370. &bError);
  2371. break;
  2372. }
  2373. DBG_EXIT(_D3D_OP_MStream_DrawPrim2, 0);
  2374. } // _D3D_OP_MStream_DrawPrim2
  2375. //-----------------------------------------------------------------------------
  2376. //
  2377. // _D3D_OP_MStream_DrawIndxP2
  2378. //
  2379. // This function processes the D3DDP2OP_DRAWINDEXEDPRIMITIVE2 DP2 command token.
  2380. //
  2381. //-----------------------------------------------------------------------------
  2382. VOID
  2383. _D3D_OP_MStream_DrawIndxP2(
  2384. P3_D3DCONTEXT* pContext,
  2385. D3DPRIMITIVETYPE primType,
  2386. INT BaseVertexOffset,
  2387. DWORD MinIndex,
  2388. DWORD NumVertices,
  2389. DWORD StartIndexOffset,
  2390. DWORD PrimitiveCount)
  2391. {
  2392. INT BaseIndexOffset;
  2393. LPDWORD lpVertices;
  2394. LPBYTE lpIndices;
  2395. BOOL bError;
  2396. R3_DP2_PRIM_TYPE_MS *pRenderFunc;
  2397. DBG_ENTRY(_D3D_OP_MStream_DrawIndxP2);
  2398. DISPDBG((DBGLVL,"_D3D_OP_MStream_DrawIndxP2 "
  2399. "primType=0x%x BaseVertexOffset=%d MinIndex=%d "
  2400. "NumVertices=%d StartIndexOffset=%d PrimitiveCount=%d",
  2401. primType, BaseVertexOffset, MinIndex,
  2402. NumVertices, StartIndexOffset, PrimitiveCount));
  2403. if (!__OP_ValidateStreams(pContext, TRUE))
  2404. {
  2405. return;
  2406. }
  2407. // The MinIndex and NumVertices parameters specify the range of vertex i
  2408. // ndices used for each DrawIndexedPrimitive call. These are used to
  2409. // optimize vertex processing of indexed primitives by processing a
  2410. // sequential range of vertices prior to indexing into these vertices
  2411. // ********** IMPORTANT NOTE **********
  2412. //
  2413. // BaseVertexOffset is a signed quantity (INT) unlike the other parameters
  2414. // to this call which are DWORDS. This may appear strange. Why would
  2415. // the offset into the vertex buffer be negative? Clearly you cannot access
  2416. // vertex data before the start of the vertex buffer, and indeed, you never
  2417. // do. When you have a negative BaseVertexOffset you will also receive
  2418. // indices which are large enough that when applied to the start pointer
  2419. // (obtained from adding a negative BaseVertexOffset to the vertex data
  2420. // pointer) which fall within the correct range of the vertices in the
  2421. // actual vertex buffer, i.e., the indices "undo" any negative vertex offset
  2422. // and vertex accesses will end up being in the legal range for that vertex
  2423. // buffer.
  2424. //
  2425. // Hence, you must write your driver code with this in mind. For example,
  2426. // you can't assume that given an index i and with a current vertex buffer
  2427. // of size v:
  2428. //
  2429. // ((StartIndexOffset + i) >= 0) && ((StartIndexOffset + i) < v)
  2430. //
  2431. // Your code needs to take into account that your indices are not offsets
  2432. // from the start of the vertex buffer but rather from the start of the
  2433. // vertex buffer plus BaseVertexOffset and that furthermore BaseVertexOffset
  2434. // may be negative.
  2435. //
  2436. // The reason BaseVertexOffset can be negative is that it provides a
  2437. // significant advantage to the runtime in certain vertex processing scenarios.
  2438. lpVertices = (LPDWORD)((LPBYTE)pContext->lpVertices + BaseVertexOffset);
  2439. lpIndices = (LPBYTE)pContext->lpIndices + StartIndexOffset;
  2440. // Select the appropriate rendering function
  2441. pRenderFunc = NULL;
  2442. if (pContext->dwIndicesStride == 2)
  2443. {
  2444. // Handle 16 bit indices
  2445. switch(primType)
  2446. {
  2447. case D3DPT_LINELIST:
  2448. pRenderFunc = _D3D_R3_DP2_IndexedLineList_MS_16IND;
  2449. break;
  2450. case D3DPT_LINESTRIP:
  2451. pRenderFunc = _D3D_R3_DP2_IndexedLineStrip_MS_16IND;
  2452. break;
  2453. case D3DPT_TRIANGLELIST:
  2454. pRenderFunc = _D3D_R3_DP2_IndexedTriangleList_MS_16IND;
  2455. break;
  2456. case D3DPT_TRIANGLESTRIP:
  2457. pRenderFunc = _D3D_R3_DP2_IndexedTriangleStrip_MS_16IND;
  2458. break;
  2459. case D3DPT_TRIANGLEFAN:
  2460. pRenderFunc = _D3D_R3_DP2_IndexedTriangleFan_MS_16IND;
  2461. break;
  2462. }
  2463. }
  2464. else
  2465. {
  2466. // Handle 32 bit indices
  2467. switch(primType)
  2468. {
  2469. case D3DPT_LINELIST:
  2470. pRenderFunc = _D3D_R3_DP2_IndexedLineList_MS_32IND;
  2471. break;
  2472. case D3DPT_LINESTRIP:
  2473. pRenderFunc = _D3D_R3_DP2_IndexedLineStrip_MS_32IND;
  2474. break;
  2475. case D3DPT_TRIANGLELIST:
  2476. pRenderFunc = _D3D_R3_DP2_IndexedTriangleList_MS_32IND;
  2477. break;
  2478. case D3DPT_TRIANGLESTRIP:
  2479. pRenderFunc = _D3D_R3_DP2_IndexedTriangleStrip_MS_32IND;
  2480. break;
  2481. case D3DPT_TRIANGLEFAN:
  2482. pRenderFunc = _D3D_R3_DP2_IndexedTriangleFan_MS_32IND;
  2483. break;
  2484. }
  2485. }
  2486. // Call our rendering function
  2487. if (pRenderFunc)
  2488. {
  2489. // As mentioned above, the actual range of indices seen by the driver
  2490. // doesn't necessarily lie within the range zero to one less than
  2491. // the number of vertices in the vertex buffer due to BaseVertexOffset.
  2492. // If BaseVertexOffset is positive the range of valid indices is
  2493. // smaller than the size of the vertex buffer (the vertices that
  2494. // lie in the vertex buffer before the BaseVertexOffset are not
  2495. // considered). Furthermore, if BaseVertexOffset a valid index can
  2496. // actually by greater than the number of vertices in the vertex
  2497. // buffer.
  2498. //
  2499. // To assist with the validation performed by the rendering functions
  2500. // we here compute a minimum and maximum index which take into
  2501. // account the value of BaseVertexOffset. Thus a test for a valid
  2502. // index becomes:
  2503. //
  2504. // ((BaseIndexOffset + StartIndexOffset + Index) >= 0) &&
  2505. // ((BaseIndexOffset + StartIndexOffset + Index) < VertexCount)
  2506. BaseIndexOffset = (BaseVertexOffset / (int)pContext->dwVerticesStride);
  2507. DISPDBG((DBGLVL,"_D3D_OP_MStream_DrawIndxP2 BaseIndexOffset = %d",
  2508. BaseIndexOffset));
  2509. (*pRenderFunc)(pContext,
  2510. PrimitiveCount,
  2511. (LPBYTE)lpIndices,
  2512. (LPD3DTLVERTEX)lpVertices,
  2513. BaseIndexOffset,
  2514. pContext->dwNumVertices,
  2515. &bError);
  2516. }
  2517. DBG_EXIT(_D3D_OP_MStream_DrawIndxP2, 0);
  2518. } // _D3D_OP_MStream_DrawIndxP2
  2519. //-----------------------------------------------------------------------------
  2520. //
  2521. // _D3D_OP_MStream_ClipTriFan
  2522. //
  2523. // This function processes the D3DDP2OP_CLIPPEDTRIANGLEFAN DP2 command token.
  2524. //
  2525. //-----------------------------------------------------------------------------
  2526. VOID
  2527. _D3D_OP_MStream_ClipTriFan(
  2528. P3_D3DCONTEXT* pContext,
  2529. DWORD FirstVertexOffset,
  2530. DWORD dwEdgeFlags,
  2531. DWORD PrimitiveCount)
  2532. {
  2533. BOOL bError;
  2534. DBG_ENTRY(_D3D_OP_MStream_ClipTriFan);
  2535. DISPDBG((DBGLVL,"_D3D_OP_MStream_ClipTriFan "
  2536. "FirstVertexOffset=%d dwEdgeFlags=0x%x PrimitiveCount=%d",
  2537. FirstVertexOffset, dwEdgeFlags, PrimitiveCount));
  2538. if (pContext->RenderStates[D3DRENDERSTATE_FILLMODE] == D3DFILL_WIREFRAME)
  2539. {
  2540. D3DHAL_DP2TRIANGLEFAN_IMM dp2TriFanWire;
  2541. if (!__OP_ValidateStreams(pContext, FALSE))
  2542. {
  2543. DBG_EXIT(_D3D_OP_MStream_ClipTriFan, 0);
  2544. return;
  2545. }
  2546. dp2TriFanWire.dwEdgeFlags = dwEdgeFlags;
  2547. _D3D_R3_DP2_TriangleFanImm(pContext,
  2548. (WORD)PrimitiveCount,
  2549. (LPBYTE)&dp2TriFanWire,
  2550. (LPD3DTLVERTEX)pContext->lpVertices,
  2551. pContext->dwNumVertices,
  2552. &bError);
  2553. }
  2554. else
  2555. {
  2556. _D3D_OP_MStream_DrawPrim2(pContext,
  2557. D3DPT_TRIANGLEFAN,
  2558. FirstVertexOffset,
  2559. PrimitiveCount);
  2560. }
  2561. DBG_EXIT(_D3D_OP_MStream_ClipTriFan, 0);
  2562. } // _D3D_OP_MStream_ClipTriFan
  2563. //-----------------------------------------------------------------------------
  2564. //
  2565. // _D3D_OP_MStream_DrawRectSurface
  2566. //
  2567. // This function processes the D3DDP2OP_DRAWRECTSURFACE DP2 command token.
  2568. //
  2569. //-----------------------------------------------------------------------------
  2570. VOID _D3D_OP_MStream_DrawRectSurface(P3_D3DCONTEXT* pContext,
  2571. DWORD Handle,
  2572. DWORD Flags,
  2573. PVOID lpPrim)
  2574. {
  2575. // High order surfaces are only supported for hw/drivers with
  2576. // TnL support and 1.0 vertex shader support
  2577. } // _D3D_OP_MStream_DrawRectSurface
  2578. //-----------------------------------------------------------------------------
  2579. //
  2580. // _D3D_OP_MStream_DrawTriSurface
  2581. //
  2582. // This function processes the D3DDP2OP_DRAWTRISURFACE DP2 command token.
  2583. //
  2584. //-----------------------------------------------------------------------------
  2585. VOID _D3D_OP_MStream_DrawTriSurface(P3_D3DCONTEXT* pContext,
  2586. DWORD Handle,
  2587. DWORD Flags,
  2588. PVOID lpPrim)
  2589. {
  2590. // High order surfaces are only supported for hw/drivers with
  2591. // TnL support and 1.0 vertex shader support
  2592. } // _D3D_OP_MStream_DrawTriSurface
  2593. #endif // DX8_MULTSTREAMS
  2594. //-----------------------------------------------------------------------------
  2595. //
  2596. // _D3D_OP_Viewport
  2597. //
  2598. // This function processes the D3DDP2OP_VIEWPORTINFO DP2 command token.
  2599. //
  2600. //-----------------------------------------------------------------------------
  2601. VOID _D3D_OP_Viewport(P3_D3DCONTEXT* pContext,
  2602. D3DHAL_DP2VIEWPORTINFO* lpvp)
  2603. {
  2604. #if DX7_D3DSTATEBLOCKS
  2605. if ( pContext->bStateRecMode )
  2606. {
  2607. _D3D_SB_Record_Viewport(pContext, lpvp);
  2608. }
  2609. else
  2610. #endif // DX7_D3DSTATEBLOCKS
  2611. {
  2612. pContext->ViewportInfo = *lpvp;
  2613. DIRTY_VIEWPORT(pContext);
  2614. }
  2615. } // _D3D_OP_Viewport
  2616. //-----------------------------------------------------------------------------
  2617. //
  2618. // _D3D_OP_ZRange
  2619. //
  2620. // This function processes the D3DDP2OP_ZRANGE DP2 command token.
  2621. //
  2622. //-----------------------------------------------------------------------------
  2623. VOID _D3D_OP_ZRange(P3_D3DCONTEXT* pContext,
  2624. D3DHAL_DP2ZRANGE* lpzr)
  2625. {
  2626. #if DX7_D3DSTATEBLOCKS
  2627. if ( pContext->bStateRecMode )
  2628. {
  2629. _D3D_SB_Record_ZRange(pContext, lpzr);
  2630. }
  2631. else
  2632. #endif // DX7_D3DSTATEBLOCKS
  2633. {
  2634. pContext->ZRange = *lpzr;
  2635. DIRTY_VIEWPORT(pContext);
  2636. }
  2637. } // _D3D_OP_ZRange
  2638. //-----------------------------------------------------------------------------
  2639. //
  2640. // _D3D_OP_UpdatePalette
  2641. //
  2642. // This function processes the D3DDP2OP_UPDATEPALETTE DP2 command token.
  2643. //
  2644. // Note : This function is need to skip D3DDP2OP_UPDATEPALETTE sent down
  2645. // by some DX6 apps, even if when PALETTE TEXTURE is not supported
  2646. // Also notice that for legacy DX apps, the palette doesn't get
  2647. // properly restored in another app transitions into full screen
  2648. // mode and back. This is because the (legacy) runtimes don't
  2649. // sent proper notification (through UpdatePalette/SetPalette) of
  2650. // this event
  2651. //
  2652. //-----------------------------------------------------------------------------
  2653. HRESULT _D3D_OP_UpdatePalette(P3_D3DCONTEXT* pContext,
  2654. D3DHAL_DP2UPDATEPALETTE* pUpdatePalette,
  2655. DWORD* pdwPalEntries)
  2656. {
  2657. #if DX7_PALETTETEXTURE
  2658. D3DHAL_DP2UPDATEPALETTE* pPalette;
  2659. P3_SURF_INTERNAL* pTexture;
  2660. // Find internal palette pointer from handle
  2661. pPalette = GetPaletteFromHandle(pContext,
  2662. pUpdatePalette->dwPaletteHandle);
  2663. // Palette doesn't exist
  2664. if (! pPalette)
  2665. {
  2666. DISPDBG((WRNLVL, "_D3D_OP_UpdatePalette : Can't find palette"));
  2667. return DDERR_INVALIDPARAMS;
  2668. }
  2669. // Check the range of palette entries
  2670. if (pUpdatePalette->wStartIndex > LUT_ENTRIES)
  2671. {
  2672. DISPDBG((WRNLVL,
  2673. "_D3D_OP_UpdatePalette : wStartIndex (%d) is bigger than 256",
  2674. pUpdatePalette->wStartIndex));
  2675. return DDERR_INVALIDPARAMS;
  2676. }
  2677. if ((pUpdatePalette->wStartIndex + pUpdatePalette->wNumEntries)
  2678. > LUT_ENTRIES)
  2679. {
  2680. DISPDBG((WRNLVL, "_D3D_OP_UpdatePalette : too many entries"));
  2681. return DDERR_INVALIDPARAMS;
  2682. }
  2683. // Each palette is ARGB 8:8:8:8
  2684. memcpy(((LPBYTE)(pPalette + 1)) + pUpdatePalette->wStartIndex*sizeof(DWORD),
  2685. pdwPalEntries,
  2686. pUpdatePalette->wNumEntries*sizeof(DWORD));
  2687. // Check if the palette is in use
  2688. // Palette Texture can not be used alone in the 2nd stage, so only the
  2689. // 1st stage must be checked.
  2690. if (pContext->TextureStageState[0].m_dwVal[D3DTSS_TEXTUREMAP])
  2691. {
  2692. pTexture = GetSurfaceFromHandle(pContext,
  2693. pContext->TextureStageState[0].m_dwVal[D3DTSS_TEXTUREMAP]);
  2694. if (pTexture)
  2695. {
  2696. if ((pTexture->pFormatSurface->DeviceFormat == SURF_CI8) &&
  2697. (pTexture->dwPaletteHandle == pUpdatePalette->dwPaletteHandle))
  2698. {
  2699. DIRTY_TEXTURE(pContext);
  2700. }
  2701. }
  2702. }
  2703. return DD_OK;
  2704. #else
  2705. return DD_OK;
  2706. #endif // DX7_PALETTETEXTURE
  2707. } // D3D_OP_UpdatePalette
  2708. //-----------------------------------------------------------------------------
  2709. //
  2710. // _D3D_OP_SetPalette
  2711. //
  2712. // This function processes the D3DDP2OP_SETPALETTE DP2 command token.
  2713. //
  2714. // Note : This function is need to skip D3DDP2OP_SETPALETTE sent down
  2715. // by some DX6 apps, even if when PALETTE TEXTURE is not supported
  2716. //
  2717. //-----------------------------------------------------------------------------
  2718. HRESULT _D3D_OP_SetPalettes(P3_D3DCONTEXT* pContext,
  2719. D3DHAL_DP2SETPALETTE* pSetPalettes,
  2720. int iNumSetPalettes)
  2721. {
  2722. #if DX7_PALETTETEXTURE
  2723. int i;
  2724. P3_SURF_INTERNAL* pTexture;
  2725. D3DHAL_DP2UPDATEPALETTE* pPalette;
  2726. // Loop to process N surface palette association
  2727. for (i = 0; i < iNumSetPalettes; i++, pSetPalettes++)
  2728. {
  2729. DISPDBG((DBGLVL,"SETPALETTE: Binding surf # %d to palette # %d",
  2730. pSetPalettes->dwSurfaceHandle,
  2731. pSetPalettes->dwPaletteHandle));
  2732. // Find internal surface pointer from handle
  2733. pTexture = GetSurfaceFromHandle(pContext,
  2734. pSetPalettes->dwSurfaceHandle);
  2735. if (! pTexture)
  2736. {
  2737. // Associated texture can't be found
  2738. DISPDBG((WRNLVL,
  2739. "SetPalettes : invalid texture handle %08lx",
  2740. pSetPalettes->dwSurfaceHandle));
  2741. return DDERR_INVALIDPARAMS;
  2742. }
  2743. // Create the internal palette structure if necessary
  2744. if (pSetPalettes->dwPaletteHandle)
  2745. {
  2746. // Find internal palette pointer from handle
  2747. pPalette = GetPaletteFromHandle(pContext,
  2748. pSetPalettes->dwPaletteHandle);
  2749. if (! pPalette)
  2750. {
  2751. pPalette = (D3DHAL_DP2UPDATEPALETTE *)
  2752. HEAP_ALLOC(FL_ZERO_MEMORY,
  2753. sizeof(D3DHAL_DP2UPDATEPALETTE)
  2754. + LUT_ENTRIES*sizeof(DWORD),
  2755. ALLOC_TAG_DX(P));
  2756. // Out of memory case
  2757. if (! pPalette)
  2758. {
  2759. DISPDBG((WRNLVL, "_D3D_OP_SetPalettes : Out of memory."));
  2760. return DDERR_OUTOFMEMORY;
  2761. }
  2762. // Add this texture to the surface list
  2763. if (! PA_SetEntry(pContext->pPalettePointerArray,
  2764. pSetPalettes->dwPaletteHandle,
  2765. pPalette))
  2766. {
  2767. HEAP_FREE(pPalette);
  2768. DISPDBG((WRNLVL, "_D3D_OP_SetPalettes : "
  2769. "PA_SetEntry() failed."));
  2770. return DDERR_OUTOFMEMORY;
  2771. }
  2772. // Set up the internal data structure
  2773. pPalette->dwPaletteHandle = pSetPalettes->dwPaletteHandle;
  2774. pPalette->wStartIndex = 0;
  2775. pPalette->wNumEntries = LUT_ENTRIES;
  2776. }
  2777. }
  2778. // Record palette handle and flags in internal surface data
  2779. pTexture->dwPaletteHandle = pSetPalettes->dwPaletteHandle;
  2780. pTexture->dwPaletteFlags = pSetPalettes->dwPaletteFlags;
  2781. // Mark texture as dirty if current texture is affected
  2782. if ((pContext->TextureStageState[0].m_dwVal[D3DTSS_TEXTUREMAP] ==
  2783. pSetPalettes->dwSurfaceHandle) ||
  2784. (pContext->TextureStageState[1].m_dwVal[D3DTSS_TEXTUREMAP] ==
  2785. pSetPalettes->dwSurfaceHandle))
  2786. {
  2787. DIRTY_TEXTURE(pContext);
  2788. }
  2789. }
  2790. return DD_OK;
  2791. #else
  2792. return DD_OK;
  2793. #endif // DX7_PALETTETEXTURE
  2794. } // _D3D_OP_SetPalettes