Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1526 lines
54 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // dprim2.cpp
  4. //
  5. // Implements DrawPrimitives2.
  6. //
  7. // Copyright (C) Microsoft Corporation, 1997.
  8. //
  9. //----------------------------------------------------------------------------
  10. #include "pch.cpp"
  11. #pragma hdrstop
  12. //---------------------------------------------------------------------
  13. // Entry is texture count. Clears all texture format bits in the FVF DWORD,
  14. // that correspond to the texture count
  15. // for this count
  16. //---------------------------------------------------------------------
  17. const DWORD g_TextureFormatMask[9] = {
  18. ~0x0000FFFF,
  19. ~0x0003FFFF,
  20. ~0x000FFFFF,
  21. ~0x003FFFFF,
  22. ~0x00FFFFFF,
  23. ~0x03FFFFFF,
  24. ~0x0FFFFFFF,
  25. ~0x3FFFFFFF,
  26. ~0xFFFFFFFF
  27. };
  28. HRESULT
  29. RDFVFCheckAndStride( DWORD dwFVF, DWORD* pdwStride )
  30. {
  31. // If the runtime is DX8+, the dwFVF might be 0
  32. // in which case the stride is obtained from the streams
  33. if( dwFVF == 0 ) return S_OK;
  34. DWORD dwTexCoord = FVF_TEXCOORD_NUMBER(dwFVF);
  35. DWORD vertexType = dwFVF & D3DFVF_POSITION_MASK;
  36. // Texture format bits above texture count should be zero
  37. // Reserved field 0 and 2 should be 0
  38. // Reserved 1 should be set only for LVERTEX
  39. // Only two vertex position types allowed
  40. if( dwFVF & g_TextureFormatMask[dwTexCoord] )
  41. {
  42. DPFERR( "FVF has incorrect texture format" );
  43. return DDERR_INVALIDPARAMS;
  44. }
  45. if( dwFVF & (D3DFVF_RESERVED2 | D3DFVF_RESERVED0) )
  46. {
  47. DPFERR( "FVF has reserved bit(s) set" );
  48. return DDERR_INVALIDPARAMS;
  49. }
  50. if( !(vertexType == D3DFVF_XYZRHW ||
  51. vertexType == D3DFVF_XYZ ||
  52. vertexType == D3DFVF_XYZB1 ||
  53. vertexType == D3DFVF_XYZB2 ||
  54. vertexType == D3DFVF_XYZB3 ||
  55. vertexType == D3DFVF_XYZB4 ||
  56. vertexType == D3DFVF_XYZB5) )
  57. {
  58. DPFERR( "FVF has incorrect position type" );
  59. return DDERR_INVALIDPARAMS;
  60. }
  61. if( (vertexType == D3DFVF_XYZRHW) && (dwFVF & D3DFVF_NORMAL) )
  62. {
  63. DPFERR( "Normal should not be used with XYZRHW position type" );
  64. return DDERR_INVALIDPARAMS;
  65. }
  66. *pdwStride = GetFVFVertexSize( dwFVF );
  67. return D3D_OK;
  68. }
  69. inline D3DPRIMITIVETYPE ConvertDP2OPToPrimType(D3DHAL_DP2OPERATION Dp2Op)
  70. {
  71. switch (Dp2Op)
  72. {
  73. case D3DDP2OP_POINTS :
  74. return D3DPT_POINTLIST;
  75. case D3DDP2OP_INDEXEDLINELIST :
  76. case D3DDP2OP_INDEXEDLINELIST2 :
  77. case D3DDP2OP_LINELIST_IMM :
  78. case D3DDP2OP_LINELIST :
  79. return D3DPT_LINELIST;
  80. case D3DDP2OP_TRIANGLELIST :
  81. case D3DDP2OP_INDEXEDTRIANGLELIST :
  82. case D3DDP2OP_INDEXEDTRIANGLELIST2:
  83. return D3DPT_TRIANGLELIST;
  84. case D3DDP2OP_LINESTRIP :
  85. case D3DDP2OP_INDEXEDLINESTRIP :
  86. return D3DPT_LINESTRIP;
  87. case D3DDP2OP_TRIANGLESTRIP :
  88. case D3DDP2OP_INDEXEDTRIANGLESTRIP:
  89. return D3DPT_TRIANGLESTRIP;
  90. case D3DDP2OP_TRIANGLEFAN :
  91. case D3DDP2OP_INDEXEDTRIANGLEFAN :
  92. case D3DDP2OP_TRIANGLEFAN_IMM :
  93. return D3DPT_TRIANGLEFAN;
  94. case D3DDP2OP_RENDERSTATE :
  95. case D3DDP2OP_TEXTURESTAGESTATE :
  96. case D3DDP2OP_VIEWPORTINFO :
  97. case D3DDP2OP_WINFO :
  98. default:
  99. DPFM(4, DRV, ("(RefRast)Non primitive operation operation in DrawPrimitives2"));
  100. return (D3DPRIMITIVETYPE)0;
  101. }
  102. }
  103. //----------------------------------------------------------------------------
  104. //
  105. // FvfToRDVertex
  106. //
  107. // Converts a series of FVF vertices to RDVertices, which are the internal
  108. // currency of the RefDev.
  109. //
  110. //----------------------------------------------------------------------------
  111. void
  112. RefDev::FvfToRDVertex( PUINT8 pVtx, GArrayT<RDVertex>& dstArray, DWORD dwFvf,
  113. DWORD dwStride, UINT cVertices )
  114. {
  115. for (DWORD i = 0; i < cVertices; i++)
  116. {
  117. dstArray[i].SetFvfData( (LPDWORD)pVtx, dwFvf );
  118. pVtx += dwStride;
  119. }
  120. }
  121. //----------------------------------------------------------------------------
  122. //
  123. // RefRastDrawPrimitives2
  124. //
  125. // This is called by D3DIM for API DrawPrimitives2 to draw a set of primitives
  126. // using a vertex buffer.
  127. //
  128. //----------------------------------------------------------------------------
  129. DWORD __stdcall
  130. RefRastDrawPrimitives2(LPD3DHAL_DRAWPRIMITIVES2DATA pDPrim2Data)
  131. {
  132. HRESULT hr = D3D_OK;
  133. RefDev *pRefDev;
  134. DWORD dwStride = 0;
  135. DWORD dwFVF = pDPrim2Data->dwVertexType;
  136. PUINT8 pVtData = NULL;
  137. PUINT8 pUMVtx = NULL;
  138. DWORD dwNumVertices = pDPrim2Data->dwVertexLength;
  139. VALIDATE_REFRAST_CONTEXT("RefRastDrawPrimitives", pDPrim2Data);
  140. if( pDPrim2Data->lpVertices )
  141. {
  142. if (pDPrim2Data->dwFlags & D3DHALDP2_USERMEMVERTICES)
  143. {
  144. pUMVtx = (PUINT8)pDPrim2Data->lpVertices;
  145. pVtData = pUMVtx + pDPrim2Data->dwVertexOffset;
  146. }
  147. else
  148. {
  149. pVtData = (PUINT8)pDPrim2Data->lpDDVertex->lpGbl->fpVidMem +
  150. pDPrim2Data->dwVertexOffset;
  151. }
  152. }
  153. LPD3DHAL_DP2COMMAND pCmd = (LPD3DHAL_DP2COMMAND)
  154. ((PUINT8)pDPrim2Data->lpDDCommands->lpGbl->fpVidMem +
  155. pDPrim2Data->dwCommandOffset);
  156. UINT_PTR CmdBoundary = (UINT_PTR)pCmd +
  157. pDPrim2Data->dwCommandLength;
  158. // Unconditionally get the vertex stride, since it can not change
  159. if ((pDPrim2Data->ddrval = RDFVFCheckAndStride(
  160. (DWORD)pDPrim2Data->dwVertexType, &dwStride)) != D3D_OK)
  161. {
  162. return DDHAL_DRIVER_HANDLED;
  163. }
  164. //
  165. // If this is a pre-DX8 DDI, then the FVF shader needs to be set as
  166. // the current shader. ONLY IF it requires vertex processing.
  167. // Else, convert its data into the RDVertex array.
  168. //
  169. if( pRefDev->GetDDIType() < RDDDI_DX8HAL )
  170. {
  171. if( !FVF_TRANSFORMED( dwFVF ) )
  172. {
  173. BYTE CmdBytes[ sizeof( D3DHAL_DP2COMMAND ) +
  174. sizeof( D3DHAL_DP2VERTEXSHADER ) ];
  175. D3DHAL_DP2COMMAND& cmd = *(LPD3DHAL_DP2COMMAND)CmdBytes;
  176. D3DHAL_DP2VERTEXSHADER& vs =
  177. *(LPD3DHAL_DP2VERTEXSHADER)((LPD3DHAL_DP2COMMAND)CmdBytes + 1);
  178. cmd.bCommand = D3DDP2OP_SETVERTEXSHADER;
  179. cmd.wStateCount = 1;
  180. vs.dwHandle = dwFVF;
  181. pRefDev->Dp2SetVertexShader( (LPD3DHAL_DP2COMMAND)CmdBytes );
  182. // Set the 0th stream here as well.
  183. pRefDev->GetVStream( 0 ).m_pData = pVtData;
  184. pRefDev->GetVStream( 0 ).m_dwStride = dwStride;
  185. }
  186. else
  187. {
  188. // Ask the RefDev to grow its TLVBuf Array and copy the
  189. // FVF data into it.
  190. HR_RET( pRefDev->GrowTLVArray( dwNumVertices ) );
  191. pRefDev->FvfToRDVertex( pVtData, pRefDev->GetTLVArray(), dwFVF,
  192. dwStride, dwNumVertices );
  193. }
  194. }
  195. // Skip state check and texture lock if the first thing is state change
  196. //
  197. // WINFO is excluded here because it currently does not affect RGB/MMX
  198. // and refrast does not care if it changes between begin/endrendering.
  199. //
  200. // VIEWPORTINFO is excluded here because it is OK to change the viewport
  201. // between begin/endrendering on both RGB/MMX and Ref.
  202. //
  203. #ifndef __D3D_NULL_REF
  204. // Loop through the data, update render states
  205. // and then draw the primitive
  206. for (;;)
  207. {
  208. LPDWORD lpdwRStates;
  209. if (pDPrim2Data->dwFlags & D3DHALDP2_EXECUTEBUFFER)
  210. lpdwRStates = pDPrim2Data->lpdwRStates;
  211. else
  212. lpdwRStates = NULL;
  213. pDPrim2Data->ddrval = pRefDev->DrawPrimitives2( pUMVtx,
  214. (UINT16)dwStride,
  215. dwFVF,
  216. dwNumVertices,
  217. &pCmd,
  218. lpdwRStates );
  219. if (pDPrim2Data->ddrval != D3D_OK)
  220. {
  221. if (pDPrim2Data->ddrval == D3DERR_COMMAND_UNPARSED)
  222. {
  223. pDPrim2Data->dwErrorOffset = (UINT32)((ULONG_PTR)pCmd -
  224. (UINT_PTR)(pDPrim2Data->lpDDCommands->lpGbl->fpVidMem));
  225. }
  226. goto EH_Exit;
  227. }
  228. if ((UINT_PTR)pCmd >= CmdBoundary)
  229. break;
  230. }
  231. EH_Exit:
  232. #else //__D3D_NULL_REF
  233. pDPrim2Data->ddrval = S_OK;
  234. #endif //__D3D_NULL_REF
  235. hr = pRefDev->EndRendering();
  236. if (pDPrim2Data->ddrval == D3D_OK)
  237. {
  238. pDPrim2Data->ddrval = hr;
  239. }
  240. return DDHAL_DRIVER_HANDLED;
  241. }
  242. #ifndef __D3D_NULL_REF
  243. HRESULT FASTCALL
  244. DoDrawIndexedTriList2( RefDev *pCtx,
  245. WORD cPrims,
  246. D3DHAL_DP2INDEXEDTRIANGLELIST *pTriList)
  247. {
  248. INT i;
  249. D3DHAL_DP2INDEXEDTRIANGLELIST *pTri = pTriList;
  250. GArrayT<RDVertex>& VtxArray = pCtx->GetTLVArray();
  251. for (i = 0; i < cPrims; i ++)
  252. {
  253. HRESULT hr;
  254. PUINT8 pVtx0, pVtx1, pVtx2;
  255. RDVertex& Vtx0 = VtxArray[pTri->wV1];
  256. RDVertex& Vtx1 = VtxArray[pTri->wV2];
  257. RDVertex& Vtx2 = VtxArray[pTri->wV3];
  258. pCtx->DrawTriangle( &Vtx0, &Vtx1, &Vtx2, pTri->wFlags);
  259. pTri ++;
  260. }
  261. return D3D_OK;
  262. }
  263. //----------------------------------------------------------------------------
  264. //
  265. // DoDrawPrimitives2
  266. //
  267. // It's called by RefRastDrawPrimitives2. .
  268. //
  269. //----------------------------------------------------------------------------
  270. HRESULT
  271. RefDev::DrawPrimitives2( PUINT8 pUMVtx,
  272. UINT16 dwStride,
  273. DWORD dwFvf,
  274. DWORD dwNumVertices,
  275. LPD3DHAL_DP2COMMAND *ppCmd,
  276. LPDWORD lpdwRStates )
  277. {
  278. LPD3DHAL_DP2COMMAND pCmd = *ppCmd;
  279. HRESULT hr = S_OK;
  280. DPFM(7, DRV, ("(RefRast)Read Ins: %08lx", *(LPDWORD)pCmd));
  281. BOOL bWireframe =
  282. (GetRS()[D3DRENDERSTATE_FILLMODE] == D3DFILL_WIREFRAME);
  283. //
  284. // Lock textures and setup the floating point state if the
  285. // command is a drawing command, only if it has not been locked before
  286. //
  287. switch(pCmd->bCommand)
  288. {
  289. case D3DDP2OP_POINTS:
  290. case D3DDP2OP_LINELIST:
  291. case D3DDP2OP_LINESTRIP:
  292. case D3DDP2OP_TRIANGLELIST:
  293. case D3DDP2OP_TRIANGLESTRIP:
  294. case D3DDP2OP_TRIANGLEFAN:
  295. case D3DDP2OP_INDEXEDLINELIST:
  296. case D3DDP2OP_INDEXEDLINELIST2:
  297. case D3DDP2OP_INDEXEDLINESTRIP:
  298. case D3DDP2OP_INDEXEDTRIANGLELIST:
  299. case D3DDP2OP_INDEXEDTRIANGLELIST2:
  300. case D3DDP2OP_INDEXEDTRIANGLESTRIP:
  301. case D3DDP2OP_INDEXEDTRIANGLEFAN:
  302. case D3DDP2OP_TRIANGLEFAN_IMM:
  303. case D3DDP2OP_LINELIST_IMM:
  304. _ASSERT( GetDDIType() < RDDDI_DX8HAL, "Older drawing tokens"
  305. " received for DX8+ DDI" );
  306. // Fall through
  307. case D3DDP2OP_DRAWPRIMITIVE:
  308. case D3DDP2OP_DRAWINDEXEDPRIMITIVE:
  309. case D3DDP2OP_CLIPPEDTRIANGLEFAN:
  310. case D3DDP2OP_DRAWPRIMITIVE2:
  311. case D3DDP2OP_DRAWINDEXEDPRIMITIVE2:
  312. case D3DDP2OP_DRAWRECTPATCH:
  313. case D3DDP2OP_DRAWTRIPATCH:
  314. // Turn off the TCI override, this will be set if needed later
  315. // on during vertex processing by the fixed function pipeline.
  316. m_bOverrideTCI = FALSE;
  317. // This stuff needs to be updated only on pre DX7 drivers.
  318. HR_RET(RefRastUpdatePalettes( this ));
  319. HR_RET(BeginRendering());
  320. }
  321. switch(pCmd->bCommand)
  322. {
  323. case D3DDP2OP_STATESET:
  324. {
  325. LPD3DHAL_DP2STATESET pStateSetOp =
  326. (LPD3DHAL_DP2STATESET)(pCmd + 1);
  327. switch (pStateSetOp->dwOperation)
  328. {
  329. case D3DHAL_STATESETBEGIN :
  330. HR_RET(BeginStateSet(pStateSetOp->dwParam));
  331. break;
  332. case D3DHAL_STATESETEND :
  333. HR_RET(EndStateSet());
  334. break;
  335. case D3DHAL_STATESETDELETE :
  336. HR_RET(DeleteStateSet(pStateSetOp->dwParam));
  337. break;
  338. case D3DHAL_STATESETEXECUTE:
  339. HR_RET(ExecuteStateSet(pStateSetOp->dwParam));
  340. break;
  341. case D3DHAL_STATESETCAPTURE:
  342. HR_RET(CaptureStateSet(pStateSetOp->dwParam));
  343. break;
  344. case D3DHAL_STATESETCREATE:
  345. HR_RET(CreateStateSet(pStateSetOp->dwParam,
  346. pStateSetOp->sbType));
  347. break;
  348. default :
  349. return DDERR_INVALIDPARAMS;
  350. }
  351. // Update the command buffer pointer
  352. *ppCmd = (LPD3DHAL_DP2COMMAND)(pStateSetOp + pCmd->wStateCount);
  353. }
  354. break;
  355. case D3DDP2OP_VIEWPORTINFO:
  356. {
  357. HR_RET(pStateSetFuncTbl->pfnDp2SetViewport(this, pCmd));
  358. // Update the command buffer pointer
  359. *ppCmd = (LPD3DHAL_DP2COMMAND)
  360. ((D3DHAL_DP2VIEWPORTINFO *)(pCmd + 1) + pCmd->wStateCount);
  361. }
  362. break;
  363. case D3DDP2OP_WINFO:
  364. {
  365. HR_RET(pStateSetFuncTbl->pfnDp2SetWRange(this, pCmd));
  366. // Update the command buffer pointer
  367. *ppCmd = (LPD3DHAL_DP2COMMAND)
  368. ((D3DHAL_DP2WINFO *)(pCmd + 1) + pCmd->wStateCount);
  369. }
  370. break;
  371. case D3DDP2OP_RENDERSTATE:
  372. {
  373. HR_RET(pStateSetFuncTbl->pfnDp2SetRenderStates(this, dwFvf, pCmd,
  374. lpdwRStates));
  375. // Update the command buffer pointer
  376. *ppCmd = (LPD3DHAL_DP2COMMAND)
  377. ((D3DHAL_DP2RENDERSTATE *)(pCmd + 1) + pCmd->wStateCount);
  378. }
  379. break;
  380. case D3DDP2OP_TEXTURESTAGESTATE:
  381. {
  382. HR_RET(pStateSetFuncTbl->pfnDp2TextureStageState(this, dwFvf,
  383. pCmd));
  384. // Update the command buffer pointer
  385. *ppCmd = (LPD3DHAL_DP2COMMAND)
  386. ((LPD3DHAL_DP2TEXTURESTAGESTATE)(pCmd + 1) + pCmd->wStateCount);
  387. }
  388. break;
  389. // This is a special case because it has edge flags. Other D3DDP2OP
  390. // can actually make use of DrawOneIndexedPrimitive/DrawOnePrimitive.
  391. case D3DDP2OP_INDEXEDTRIANGLELIST:
  392. {
  393. // This command is used in execute buffers. So untransformed
  394. // vertices are not expected by this refrast.
  395. _ASSERT( FVF_TRANSFORMED(dwFvf), "Untransformed vertices in "
  396. "D3DDP2OP_INDEXEDTRIANGLELIST" );
  397. WORD cPrims = pCmd->wPrimitiveCount;
  398. HR_RET(DoDrawIndexedTriList2(
  399. this, cPrims, (D3DHAL_DP2INDEXEDTRIANGLELIST *)(pCmd + 1)));
  400. // Update the command buffer pointer
  401. *ppCmd = (LPD3DHAL_DP2COMMAND)((PUINT8)(pCmd + 1) +
  402. sizeof(D3DHAL_DP2INDEXEDTRIANGLELIST) * cPrims);
  403. }
  404. break;
  405. case D3DDP2OP_INDEXEDLINELIST:
  406. {
  407. // This command is used in execute buffers. So untransformed
  408. // vertices are not expected by this refrast.
  409. _ASSERT( FVF_TRANSFORMED(dwFvf),
  410. "Untransformed vertices in D3DDP2OP_INDEXEDLINELIST" );
  411. HR_RET(DrawOneIndexedPrimitive( GetTLVArray(),
  412. 0,
  413. (LPWORD)(pCmd + 1),
  414. 0,
  415. pCmd->wPrimitiveCount * 2,
  416. D3DPT_LINELIST));
  417. // Update the command buffer pointer
  418. *ppCmd = (LPD3DHAL_DP2COMMAND)((PUINT8)(pCmd + 1) +
  419. pCmd->wPrimitiveCount * sizeof(D3DHAL_DP2INDEXEDLINELIST));
  420. }
  421. break;
  422. // Following ops All use DrawOneIndexedPrimitive/DrawOnePrimitive.
  423. // There are some extra overheads introduced because those two functions
  424. // need to switch over the PrimTypes while we already know it here.
  425. // Striping out the code to add inline functions for each PrimType means
  426. // adding about twenty functions(considering the types of prim times types
  427. // of vertex). So I have used DrawOneIndexedPrimitive/DrawOnePrimitive
  428. // here anyway. We can later change it if necessary.
  429. case D3DDP2OP_POINTS:
  430. {
  431. WORD cPrims = pCmd->wPrimitiveCount;
  432. D3DHAL_DP2POINTS *pPt = (D3DHAL_DP2POINTS *)(pCmd + 1);
  433. WORD i;
  434. // Check if the primitive is transformed or not
  435. if (!FVF_TRANSFORMED(dwFvf))
  436. {
  437. for (i = 0; i < cPrims; i++)
  438. {
  439. HR_RET(ProcessPrimitive( D3DPT_POINTLIST,
  440. pPt->wVStart,
  441. pPt->wCount,
  442. 0, 0 ));
  443. pPt ++;
  444. }
  445. }
  446. else
  447. {
  448. if( GetRS()[D3DRENDERSTATE_CLIPPING] )
  449. {
  450. HR_RET( UpdateClipper() );
  451. for (i = 0; i < cPrims; i++)
  452. {
  453. HR_RET(m_Clipper.DrawOnePrimitive( GetTLVArray(),
  454. pPt->wVStart,
  455. D3DPT_POINTLIST,
  456. pPt->wCount));
  457. // Clean up the FVFP_CLIP bit for the
  458. // copied vertices.
  459. pPt ++;
  460. }
  461. }
  462. else
  463. {
  464. for (i = 0; i < cPrims; i++)
  465. {
  466. HR_RET(DrawOnePrimitive( GetTLVArray(),
  467. pPt->wVStart,
  468. D3DPT_POINTLIST,
  469. pPt->wCount));
  470. pPt ++;
  471. }
  472. }
  473. }
  474. // Update the command buffer pointer
  475. *ppCmd = (LPD3DHAL_DP2COMMAND)pPt;
  476. }
  477. break;
  478. case D3DDP2OP_LINELIST:
  479. {
  480. D3DHAL_DP2LINELIST *pLine = (D3DHAL_DP2LINELIST *)(pCmd + 1);
  481. // Check if the primitive is transformed or not
  482. if (!FVF_TRANSFORMED(dwFvf))
  483. {
  484. HR_RET(ProcessPrimitive( D3DPT_LINELIST, pLine->wVStart,
  485. pCmd->wPrimitiveCount * 2, 0, 0 ));
  486. }
  487. else
  488. {
  489. if( GetRS()[D3DRENDERSTATE_CLIPPING] )
  490. {
  491. HR_RET( UpdateClipper() );
  492. HR_RET(m_Clipper.DrawOnePrimitive(
  493. GetTLVArray(),
  494. pLine->wVStart,
  495. D3DPT_LINELIST,
  496. pCmd->wPrimitiveCount * 2));
  497. // Clean up the FVFP_CLIP bit for the
  498. // copied vertices.
  499. }
  500. else
  501. {
  502. HR_RET(DrawOnePrimitive(
  503. GetTLVArray(),
  504. pLine->wVStart,
  505. D3DPT_LINELIST,
  506. pCmd->wPrimitiveCount * 2));
  507. }
  508. }
  509. // Update the command buffer pointer
  510. *ppCmd = (LPD3DHAL_DP2COMMAND)(pLine + 1);
  511. }
  512. break;
  513. case D3DDP2OP_INDEXEDLINELIST2:
  514. {
  515. DWORD dwNumIndices = pCmd->wPrimitiveCount*2;
  516. LPD3DHAL_DP2STARTVERTEX lpStartVertex =
  517. (LPD3DHAL_DP2STARTVERTEX)(pCmd + 1);
  518. // Set the Index Stream
  519. m_IndexStream.m_pData = (LPBYTE)(lpStartVertex + 1);
  520. m_IndexStream.m_dwStride = 2;
  521. // Check if the primitive is transformed or not
  522. if (!FVF_TRANSFORMED(dwFvf))
  523. {
  524. HR_RET(ProcessPrimitive(
  525. D3DPT_LINELIST,
  526. lpStartVertex->wVStart,
  527. dwNumVertices-lpStartVertex->wVStart,
  528. 0,
  529. dwNumIndices ));
  530. }
  531. else
  532. {
  533. if( GetRS()[D3DRENDERSTATE_CLIPPING] )
  534. {
  535. HR_RET( UpdateClipper() );
  536. HR_RET(m_Clipper.DrawOneIndexedPrimitive(
  537. GetTLVArray(),
  538. lpStartVertex->wVStart,
  539. (LPWORD)(lpStartVertex + 1),
  540. 0,
  541. dwNumIndices,
  542. D3DPT_LINELIST));
  543. // Clean up the FVFP_CLIP bit for the
  544. // copied vertices.
  545. }
  546. else
  547. {
  548. HR_RET(DrawOneIndexedPrimitive(
  549. GetTLVArray(),
  550. lpStartVertex->wVStart,
  551. (LPWORD)(lpStartVertex + 1),
  552. 0,
  553. dwNumIndices,
  554. D3DPT_LINELIST));
  555. }
  556. }
  557. // Update the command buffer pointer
  558. *ppCmd = (LPD3DHAL_DP2COMMAND)((PUINT8)(lpStartVertex + 1) +
  559. pCmd->wPrimitiveCount * sizeof(D3DHAL_DP2INDEXEDLINELIST));
  560. }
  561. break;
  562. case D3DDP2OP_LINESTRIP:
  563. {
  564. D3DHAL_DP2LINESTRIP *pLine = (D3DHAL_DP2LINESTRIP *)(pCmd + 1);
  565. // Check if the primitive is transformed or not
  566. if (!FVF_TRANSFORMED(dwFvf))
  567. {
  568. HR_RET(ProcessPrimitive( D3DPT_LINESTRIP,
  569. pLine->wVStart,
  570. pCmd->wPrimitiveCount + 1,
  571. 0, 0 ));
  572. }
  573. else
  574. {
  575. if( GetRS()[D3DRENDERSTATE_CLIPPING] )
  576. {
  577. HR_RET( UpdateClipper() );
  578. HR_RET(m_Clipper.DrawOnePrimitive(
  579. GetTLVArray(),
  580. pLine->wVStart,
  581. D3DPT_LINESTRIP,
  582. pCmd->wPrimitiveCount + 1));
  583. // Clean up the FVFP_CLIP bit for the
  584. // copied vertices.
  585. }
  586. else
  587. {
  588. HR_RET(DrawOnePrimitive(
  589. GetTLVArray(),
  590. pLine->wVStart,
  591. D3DPT_LINESTRIP,
  592. pCmd->wPrimitiveCount + 1));
  593. }
  594. }
  595. // Update the command buffer pointer
  596. *ppCmd = (LPD3DHAL_DP2COMMAND)(pLine + 1);
  597. }
  598. break;
  599. case D3DDP2OP_INDEXEDLINESTRIP:
  600. {
  601. DWORD dwNumIndices = pCmd->wPrimitiveCount + 1;
  602. LPD3DHAL_DP2STARTVERTEX lpStartVertex =
  603. (LPD3DHAL_DP2STARTVERTEX)(pCmd + 1);
  604. // Set the Index Stream
  605. m_IndexStream.m_pData = (LPBYTE)(lpStartVertex + 1);
  606. m_IndexStream.m_dwStride = 2;
  607. // Check if the primitive is transformed or not
  608. if (!FVF_TRANSFORMED(dwFvf))
  609. {
  610. HR_RET(ProcessPrimitive(
  611. D3DPT_LINESTRIP,
  612. lpStartVertex->wVStart,
  613. dwNumVertices-lpStartVertex->wVStart,
  614. 0,
  615. dwNumIndices ));
  616. }
  617. else
  618. {
  619. if( GetRS()[D3DRENDERSTATE_CLIPPING] )
  620. {
  621. HR_RET( UpdateClipper() );
  622. HR_RET(m_Clipper.DrawOneIndexedPrimitive(
  623. GetTLVArray(),
  624. lpStartVertex->wVStart,
  625. (LPWORD)(lpStartVertex + 1),
  626. 0,
  627. dwNumIndices,
  628. D3DPT_LINESTRIP));
  629. // Clean up the FVFP_CLIP bit for the
  630. // copied vertices.
  631. }
  632. else
  633. {
  634. HR_RET(DrawOneIndexedPrimitive(
  635. GetTLVArray(),
  636. lpStartVertex->wVStart,
  637. (LPWORD)(lpStartVertex + 1),
  638. 0,
  639. dwNumIndices,
  640. D3DPT_LINESTRIP));
  641. }
  642. }
  643. // Update the command buffer pointer
  644. *ppCmd = (LPD3DHAL_DP2COMMAND)((PUINT8)(lpStartVertex + 1) +
  645. dwNumIndices * sizeof(WORD));
  646. }
  647. break;
  648. case D3DDP2OP_TRIANGLELIST:
  649. {
  650. D3DHAL_DP2TRIANGLELIST *pTri = (D3DHAL_DP2TRIANGLELIST *)(pCmd + 1);
  651. // Check if the primitive is transformed or not
  652. if (!FVF_TRANSFORMED(dwFvf))
  653. {
  654. HR_RET(ProcessPrimitive( D3DPT_TRIANGLELIST,
  655. pTri->wVStart,
  656. pCmd->wPrimitiveCount * 3,
  657. 0, 0 ));
  658. }
  659. else
  660. {
  661. if( GetRS()[D3DRENDERSTATE_CLIPPING] )
  662. {
  663. HR_RET( UpdateClipper() );
  664. HR_RET(m_Clipper.DrawOnePrimitive(
  665. GetTLVArray(),
  666. pTri->wVStart,
  667. D3DPT_TRIANGLELIST,
  668. pCmd->wPrimitiveCount * 3));
  669. // Clean up the FVFP_CLIP bit for the
  670. // copied vertices.
  671. }
  672. else
  673. {
  674. HR_RET(DrawOnePrimitive( GetTLVArray(),
  675. pTri->wVStart,
  676. D3DPT_TRIANGLELIST,
  677. pCmd->wPrimitiveCount * 3));
  678. }
  679. }
  680. // Update the command buffer pointer
  681. *ppCmd = (LPD3DHAL_DP2COMMAND)(pTri + 1);
  682. }
  683. break;
  684. case D3DDP2OP_INDEXEDTRIANGLELIST2:
  685. {
  686. DWORD dwNumIndices = pCmd->wPrimitiveCount*3;
  687. LPD3DHAL_DP2STARTVERTEX lpStartVertex =
  688. (LPD3DHAL_DP2STARTVERTEX)(pCmd + 1);
  689. // Set the Index Stream
  690. m_IndexStream.m_pData = (LPBYTE)(lpStartVertex + 1);
  691. m_IndexStream.m_dwStride = 2;
  692. // Check if the primitive is transformed or not
  693. if (!FVF_TRANSFORMED(dwFvf))
  694. {
  695. HR_RET(ProcessPrimitive(
  696. D3DPT_TRIANGLELIST,
  697. lpStartVertex->wVStart,
  698. dwNumVertices-lpStartVertex->wVStart,
  699. 0,
  700. dwNumIndices));
  701. }
  702. else
  703. {
  704. if( GetRS()[D3DRENDERSTATE_CLIPPING] )
  705. {
  706. HR_RET( UpdateClipper() );
  707. HR_RET(m_Clipper.DrawOneIndexedPrimitive(
  708. GetTLVArray(),
  709. lpStartVertex->wVStart,
  710. (LPWORD)(lpStartVertex + 1),
  711. 0,
  712. dwNumIndices,
  713. D3DPT_TRIANGLELIST));
  714. // Clean up the FVFP_CLIP bit for the
  715. // copied vertices.
  716. }
  717. else
  718. {
  719. HR_RET(DrawOneIndexedPrimitive(
  720. GetTLVArray(),
  721. lpStartVertex->wVStart,
  722. (LPWORD)(lpStartVertex + 1),
  723. 0,
  724. dwNumIndices,
  725. D3DPT_TRIANGLELIST));
  726. }
  727. }
  728. // Update the command buffer pointer
  729. *ppCmd = (LPD3DHAL_DP2COMMAND)((PUINT8)(lpStartVertex + 1) +
  730. dwNumIndices * sizeof(WORD));
  731. }
  732. break;
  733. case D3DDP2OP_TRIANGLESTRIP:
  734. {
  735. D3DHAL_DP2TRIANGLESTRIP *pTri = (D3DHAL_DP2TRIANGLESTRIP *)(pCmd + 1);
  736. // Check if the primitive is transformed or not
  737. if (!FVF_TRANSFORMED(dwFvf))
  738. {
  739. HR_RET(ProcessPrimitive( D3DPT_TRIANGLESTRIP,
  740. pTri->wVStart,
  741. pCmd->wPrimitiveCount + 2,
  742. 0, 0 ));
  743. }
  744. else
  745. {
  746. if( GetRS()[D3DRENDERSTATE_CLIPPING] )
  747. {
  748. HR_RET( UpdateClipper() );
  749. HR_RET(m_Clipper.DrawOnePrimitive(
  750. GetTLVArray(),
  751. pTri->wVStart,
  752. D3DPT_TRIANGLESTRIP,
  753. pCmd->wPrimitiveCount + 2));
  754. // Clean up the FVFP_CLIP bit for the
  755. // copied vertices.
  756. }
  757. else
  758. {
  759. HR_RET(DrawOnePrimitive(
  760. GetTLVArray(),
  761. pTri->wVStart,
  762. D3DPT_TRIANGLESTRIP,
  763. pCmd->wPrimitiveCount + 2));
  764. }
  765. }
  766. // Update the command buffer pointer
  767. *ppCmd = (LPD3DHAL_DP2COMMAND)(pTri + 1);
  768. }
  769. break;
  770. case D3DDP2OP_INDEXEDTRIANGLESTRIP:
  771. {
  772. DWORD dwNumIndices = pCmd->wPrimitiveCount+2;
  773. LPD3DHAL_DP2STARTVERTEX lpStartVertex =
  774. (LPD3DHAL_DP2STARTVERTEX)(pCmd + 1);
  775. // Set the Index Stream
  776. m_IndexStream.m_pData = (LPBYTE)(lpStartVertex + 1);
  777. m_IndexStream.m_dwStride = 2;
  778. // Check if the primitive is transformed or not
  779. if (!FVF_TRANSFORMED(dwFvf))
  780. {
  781. HR_RET(ProcessPrimitive(
  782. D3DPT_TRIANGLESTRIP,
  783. lpStartVertex->wVStart,
  784. dwNumVertices-lpStartVertex->wVStart,
  785. 0,
  786. dwNumIndices ));
  787. }
  788. else
  789. {
  790. if( GetRS()[D3DRENDERSTATE_CLIPPING] )
  791. {
  792. HR_RET( UpdateClipper() );
  793. HR_RET(m_Clipper.DrawOneIndexedPrimitive(
  794. GetTLVArray(),
  795. lpStartVertex->wVStart,
  796. (LPWORD)(lpStartVertex + 1),
  797. 0,
  798. dwNumIndices,
  799. D3DPT_TRIANGLESTRIP));
  800. // Clean up the FVFP_CLIP bit for the
  801. // copied vertices.
  802. }
  803. else
  804. {
  805. HR_RET(DrawOneIndexedPrimitive(
  806. GetTLVArray(),
  807. lpStartVertex->wVStart,
  808. (LPWORD)(lpStartVertex + 1),
  809. 0,
  810. dwNumIndices,
  811. D3DPT_TRIANGLESTRIP));
  812. }
  813. }
  814. // Update the command buffer pointer
  815. *ppCmd = (LPD3DHAL_DP2COMMAND)((PUINT8)(lpStartVertex + 1) +
  816. dwNumIndices * sizeof(WORD));
  817. }
  818. break;
  819. case D3DDP2OP_TRIANGLEFAN:
  820. {
  821. D3DHAL_DP2TRIANGLEFAN *pTri = (D3DHAL_DP2TRIANGLEFAN *)(pCmd + 1);
  822. // Check if the primitive is transformed or not
  823. if (!FVF_TRANSFORMED(dwFvf))
  824. {
  825. HR_RET(ProcessPrimitive( D3DPT_TRIANGLEFAN,
  826. pTri->wVStart,
  827. pCmd->wPrimitiveCount + 2,
  828. 0, 0 ));
  829. }
  830. else
  831. {
  832. if( GetRS()[D3DRENDERSTATE_CLIPPING] )
  833. {
  834. HR_RET( UpdateClipper() );
  835. HR_RET(m_Clipper.DrawOnePrimitive(
  836. GetTLVArray(),
  837. pTri->wVStart,
  838. D3DPT_TRIANGLEFAN,
  839. pCmd->wPrimitiveCount + 2));
  840. // Clean up the FVFP_CLIP bit for the
  841. // copied vertices.
  842. }
  843. else
  844. {
  845. HR_RET(DrawOnePrimitive(
  846. GetTLVArray(),
  847. pTri->wVStart,
  848. D3DPT_TRIANGLEFAN,
  849. pCmd->wPrimitiveCount + 2));
  850. }
  851. }
  852. // Update the command buffer pointer
  853. *ppCmd = (LPD3DHAL_DP2COMMAND)(pTri + 1);
  854. }
  855. break;
  856. case D3DDP2OP_INDEXEDTRIANGLEFAN:
  857. {
  858. DWORD dwNumIndices = pCmd->wPrimitiveCount + 2;
  859. LPD3DHAL_DP2STARTVERTEX lpStartVertex =
  860. (LPD3DHAL_DP2STARTVERTEX)(pCmd + 1);
  861. // Set the Index Stream
  862. m_IndexStream.m_pData = (LPBYTE)(lpStartVertex + 1);
  863. m_IndexStream.m_dwStride = 2;
  864. // Check if the primitive is transformed or not
  865. if (!FVF_TRANSFORMED(dwFvf))
  866. {
  867. HR_RET(ProcessPrimitive(
  868. D3DPT_TRIANGLEFAN,
  869. lpStartVertex->wVStart,
  870. dwNumVertices-lpStartVertex->wVStart,
  871. 0,
  872. dwNumIndices ));
  873. }
  874. else
  875. {
  876. if( GetRS()[D3DRENDERSTATE_CLIPPING] )
  877. {
  878. HR_RET( UpdateClipper() );
  879. HR_RET(m_Clipper.DrawOneIndexedPrimitive(
  880. GetTLVArray(),
  881. lpStartVertex->wVStart,
  882. (LPWORD)(lpStartVertex + 1),
  883. 0,
  884. dwNumIndices,
  885. D3DPT_TRIANGLEFAN));
  886. // Clean up the FVFP_CLIP bit for the
  887. // copied vertices.
  888. }
  889. else
  890. {
  891. HR_RET(DrawOneIndexedPrimitive(
  892. GetTLVArray(),
  893. lpStartVertex->wVStart,
  894. (LPWORD)(lpStartVertex + 1),
  895. 0,
  896. dwNumIndices,
  897. D3DPT_TRIANGLEFAN));
  898. }
  899. }
  900. // Update the command buffer pointer
  901. *ppCmd = (LPD3DHAL_DP2COMMAND)((PUINT8)(lpStartVertex + 1) +
  902. dwNumIndices * sizeof(WORD));
  903. }
  904. break;
  905. case D3DDP2OP_TRIANGLEFAN_IMM:
  906. {
  907. DWORD vertexCount = pCmd->wPrimitiveCount + 2;
  908. // Make sure the pFanVtx pointer is DWORD aligned: (pFanVtx +3) % 4
  909. PUINT8 pFanVtx = (PUINT8)
  910. (((ULONG_PTR)(pCmd + 1) +
  911. sizeof(D3DHAL_DP2TRIANGLEFAN_IMM) + 3) & ~3);
  912. // Assert here. This case should never be reached.
  913. // This command is used by front end to give clipped
  914. // primitives inside the command itself. Since TL Hals
  915. // do their own clipping untransformed vertices but yet
  916. // clipped are not expected here.
  917. // Assert that only transformed vertices can reach here
  918. _ASSERT( FVF_TRANSFORMED(dwFvf),
  919. "Untransformed vertices in D3DDP2OP_TRIANGLEFAN_IMM" );
  920. GArrayT<RDVertex> ClipVtxArray;
  921. HR_RET(ClipVtxArray.Grow( vertexCount ) );
  922. FvfToRDVertex( pFanVtx, ClipVtxArray, dwFvf, dwStride,
  923. vertexCount );
  924. if (bWireframe)
  925. {
  926. // Read edge flags
  927. UINT32 dwEdgeFlags =
  928. ((LPD3DHAL_DP2TRIANGLEFAN_IMM)(pCmd + 1))->dwEdgeFlags;
  929. HR_RET(DrawOneEdgeFlagTriangleFan( ClipVtxArray,
  930. vertexCount,
  931. dwEdgeFlags));
  932. }
  933. else
  934. {
  935. HR_RET(DrawOnePrimitive( ClipVtxArray,
  936. 0,
  937. D3DPT_TRIANGLEFAN,
  938. vertexCount));
  939. }
  940. // Update the command buffer pointer
  941. *ppCmd = (LPD3DHAL_DP2COMMAND)((PUINT8)pFanVtx +
  942. vertexCount * dwStride);
  943. }
  944. break;
  945. case D3DDP2OP_LINELIST_IMM:
  946. {
  947. DWORD vertexCount = pCmd->wPrimitiveCount * 2;
  948. // Make sure the pLineVtx pointer is DWORD aligned:
  949. // (pLineVtx +3) % 4
  950. PUINT8 pLineVtx = (PUINT8)(((ULONG_PTR)(pCmd + 1) + 3) & ~3);
  951. // Assert here. This case should never be reached.
  952. // This command is used by front end to give clipped
  953. // primitives inside the command itself. Since TL Hals
  954. // do their own clipping untransformed vertices but yet
  955. // clipped are not expected here.
  956. // Assert that only transformed vertices can reach here
  957. _ASSERT( FVF_TRANSFORMED(dwFvf),
  958. "Untransformed vertices in D3DDP2OP_LINELIST_IMM" );
  959. GArrayT<RDVertex> ClipVtxArray;
  960. HR_RET(ClipVtxArray.Grow( vertexCount ) );
  961. FvfToRDVertex( pLineVtx, ClipVtxArray, dwFvf, dwStride,
  962. vertexCount );
  963. HR_RET(DrawOnePrimitive( ClipVtxArray,
  964. 0,
  965. D3DPT_LINELIST,
  966. vertexCount));
  967. // Update the command buffer pointer
  968. *ppCmd = (LPD3DHAL_DP2COMMAND)((PUINT8)pLineVtx +
  969. vertexCount * dwStride);
  970. }
  971. break;
  972. case D3DDP2OP_DRAWPRIMITIVE:
  973. {
  974. HR_RET(Dp2DrawPrimitive(pCmd));
  975. // Update the command buffer pointer
  976. *ppCmd = (LPD3DHAL_DP2COMMAND)
  977. ((D3DHAL_DP2DRAWPRIMITIVE *)(pCmd + 1) + pCmd->wStateCount);
  978. }
  979. break;
  980. case D3DDP2OP_DRAWPRIMITIVE2:
  981. {
  982. HR_RET(Dp2DrawPrimitive2(pCmd));
  983. // Update the command buffer pointer
  984. *ppCmd = (LPD3DHAL_DP2COMMAND)
  985. ((D3DHAL_DP2DRAWPRIMITIVE2 *)(pCmd + 1) + pCmd->wStateCount);
  986. }
  987. break;
  988. case D3DDP2OP_DRAWRECTPATCH:
  989. {
  990. LPD3DHAL_DP2DRAWRECTPATCH pDP =
  991. (LPD3DHAL_DP2DRAWRECTPATCH)(pCmd + 1);
  992. for( int i = 0; i < pCmd->wStateCount; i++ )
  993. {
  994. HR_RET(DrawRectPatch(pDP));
  995. bool hassegs = (pDP->Flags & RTPATCHFLAG_HASSEGS) != 0;
  996. bool hasinfo = (pDP->Flags & RTPATCHFLAG_HASINFO) != 0;
  997. if(hassegs)
  998. {
  999. pDP = (LPD3DHAL_DP2DRAWRECTPATCH)((BYTE*)(pDP + 1) +
  1000. sizeof(FLOAT) * 4);
  1001. }
  1002. else
  1003. {
  1004. ++pDP;
  1005. }
  1006. if(hasinfo)
  1007. {
  1008. pDP = (LPD3DHAL_DP2DRAWRECTPATCH)((BYTE*)pDP + sizeof(D3DRECTPATCH_INFO));
  1009. }
  1010. }
  1011. // Update the command buffer pointer
  1012. *ppCmd = (LPD3DHAL_DP2COMMAND)pDP;
  1013. }
  1014. break;
  1015. case D3DDP2OP_DRAWTRIPATCH:
  1016. {
  1017. LPD3DHAL_DP2DRAWTRIPATCH pDP =
  1018. (LPD3DHAL_DP2DRAWTRIPATCH)(pCmd + 1);
  1019. for( int i = 0; i < pCmd->wStateCount; i++ )
  1020. {
  1021. HR_RET(DrawTriPatch(pDP));
  1022. bool hassegs = (pDP->Flags & RTPATCHFLAG_HASSEGS) != 0;
  1023. bool hasinfo = (pDP->Flags & RTPATCHFLAG_HASINFO) != 0;
  1024. if(hassegs)
  1025. {
  1026. pDP = (LPD3DHAL_DP2DRAWTRIPATCH)((BYTE*)(pDP + 1) +
  1027. sizeof(FLOAT) * 3);
  1028. }
  1029. else
  1030. {
  1031. ++pDP;
  1032. }
  1033. if(hasinfo)
  1034. {
  1035. pDP = (LPD3DHAL_DP2DRAWTRIPATCH)((BYTE*)pDP + sizeof(D3DTRIPATCH_INFO));
  1036. }
  1037. }
  1038. // Update the command buffer pointer
  1039. *ppCmd = (LPD3DHAL_DP2COMMAND)pDP;
  1040. }
  1041. break;
  1042. case D3DDP2OP_DRAWINDEXEDPRIMITIVE:
  1043. {
  1044. HR_RET(Dp2DrawIndexedPrimitive(pCmd));
  1045. // Update the command buffer pointer
  1046. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1047. ((D3DHAL_DP2DRAWINDEXEDPRIMITIVE *)(pCmd + 1) +
  1048. pCmd->wStateCount);
  1049. }
  1050. break;
  1051. case D3DDP2OP_DRAWINDEXEDPRIMITIVE2:
  1052. {
  1053. HR_RET(Dp2DrawIndexedPrimitive2(pCmd));
  1054. // Update the command buffer pointer
  1055. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1056. ((D3DHAL_DP2DRAWINDEXEDPRIMITIVE2 *)(pCmd + 1) +
  1057. pCmd->wStateCount);
  1058. }
  1059. break;
  1060. case D3DDP2OP_CLIPPEDTRIANGLEFAN:
  1061. {
  1062. HR_RET(Dp2DrawClippedTriFan(pCmd));
  1063. // Update the command buffer pointer
  1064. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1065. ((D3DHAL_CLIPPEDTRIANGLEFAN*)(pCmd + 1) + pCmd->wStateCount);
  1066. }
  1067. break;
  1068. case D3DDP2OP_ZRANGE:
  1069. {
  1070. HR_RET(pStateSetFuncTbl->pfnDp2SetZRange(this, pCmd));
  1071. // Update the command buffer pointer
  1072. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1073. ((D3DHAL_DP2ZRANGE *)(pCmd + 1) + pCmd->wStateCount);
  1074. }
  1075. break;
  1076. case D3DDP2OP_SETMATERIAL:
  1077. {
  1078. HR_RET(pStateSetFuncTbl->pfnDp2SetMaterial(this, pCmd));
  1079. // Update the command buffer pointer
  1080. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1081. ((D3DHAL_DP2SETMATERIAL *)(pCmd + 1) + pCmd->wStateCount);
  1082. }
  1083. break;
  1084. case D3DDP2OP_SETLIGHT:
  1085. {
  1086. DWORD dwSLStride = 0;
  1087. HR_RET(pStateSetFuncTbl->pfnDp2SetLight(this, pCmd, &dwSLStride));
  1088. *ppCmd = (LPD3DHAL_DP2COMMAND)((LPBYTE)pCmd + dwSLStride);
  1089. }
  1090. break;
  1091. case D3DDP2OP_CREATELIGHT:
  1092. {
  1093. HR_RET(pStateSetFuncTbl->pfnDp2CreateLight(this, pCmd));
  1094. // Update the command buffer pointer
  1095. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1096. ((D3DHAL_DP2CREATELIGHT *)(pCmd + 1) + pCmd->wStateCount);
  1097. }
  1098. break;
  1099. case D3DDP2OP_SETTRANSFORM:
  1100. {
  1101. HR_RET(pStateSetFuncTbl->pfnDp2SetTransform(this, pCmd));
  1102. // Update the command buffer pointer
  1103. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1104. ((D3DHAL_DP2SETTRANSFORM *)(pCmd + 1) + pCmd->wStateCount);
  1105. }
  1106. break;
  1107. case D3DDP2OP_MULTIPLYTRANSFORM:
  1108. {
  1109. HR_RET(pStateSetFuncTbl->pfnDp2MultiplyTransform(this, pCmd));
  1110. // Update the command buffer pointer
  1111. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1112. ((D3DHAL_DP2MULTIPLYTRANSFORM *)(pCmd + 1) + pCmd->wStateCount);
  1113. }
  1114. break;
  1115. case D3DDP2OP_EXT:
  1116. {
  1117. HR_RET(pStateSetFuncTbl->pfnDp2SetExtention(this, pCmd));
  1118. // Update the command buffer pointer
  1119. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1120. ((D3DHAL_DP2EXT *)(pCmd + 1) + pCmd->wStateCount);
  1121. }
  1122. break;
  1123. case D3DDP2OP_SETRENDERTARGET:
  1124. {
  1125. HR_RET(Dp2SetRenderTarget(pCmd));
  1126. // Update the command buffer pointer
  1127. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1128. ((D3DHAL_DP2SETRENDERTARGET*)(pCmd + 1) + pCmd->wStateCount);
  1129. }
  1130. break;
  1131. case D3DDP2OP_CLEAR:
  1132. {
  1133. HR_RET(Clear(pCmd));
  1134. // Update the command buffer pointer
  1135. *ppCmd = (LPD3DHAL_DP2COMMAND)((LPBYTE)(pCmd + 1) +
  1136. sizeof(D3DHAL_DP2CLEAR) + (pCmd->wStateCount - 1) * sizeof(RECT));
  1137. }
  1138. break;
  1139. case D3DDP2OP_SETCLIPPLANE:
  1140. {
  1141. HR_RET(pStateSetFuncTbl->pfnDp2SetClipPlane(this, pCmd));
  1142. // Update the command buffer pointer
  1143. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1144. ((D3DHAL_DP2SETCLIPPLANE *)(pCmd + 1) + pCmd->wStateCount);
  1145. }
  1146. break;
  1147. case D3DOP_SPAN:
  1148. // Skip over
  1149. *ppCmd = (LPD3DHAL_DP2COMMAND)((LPBYTE)(pCmd + 1) +
  1150. pCmd->wPrimitiveCount * pCmd->bReserved );
  1151. break;
  1152. case D3DDP2OP_CREATEVERTEXSHADER:
  1153. {
  1154. LPD3DHAL_DP2CREATEVERTEXSHADER pCVS =
  1155. (LPD3DHAL_DP2CREATEVERTEXSHADER)(pCmd + 1);
  1156. WORD i;
  1157. for( i = 0; i < pCmd->wStateCount ; i++ )
  1158. {
  1159. LPDWORD pDecl = (LPDWORD)(pCVS + 1);
  1160. LPDWORD pCode = (LPDWORD)((LPBYTE)pDecl + pCVS->dwDeclSize);
  1161. hr = Dp2CreateVertexShader( pCVS->dwHandle,
  1162. pCVS->dwDeclSize, pDecl,
  1163. pCVS->dwCodeSize, pCode );
  1164. if( FAILED( hr ) ) break;
  1165. // Update the pointer
  1166. pCVS = (LPD3DHAL_DP2CREATEVERTEXSHADER)((LPBYTE)pCode +
  1167. pCVS->dwCodeSize);
  1168. }
  1169. // Successful termination of the loop:
  1170. // Update the command buffer pointer
  1171. if( i == pCmd->wStateCount )
  1172. *ppCmd = (LPD3DHAL_DP2COMMAND)pCVS;
  1173. else
  1174. return hr;
  1175. break;
  1176. }
  1177. case D3DDP2OP_DELETEVERTEXSHADER:
  1178. HR_RET(Dp2DeleteVertexShader(pCmd));
  1179. // Update the command buffer pointer
  1180. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1181. ((D3DHAL_DP2VERTEXSHADER *)(pCmd + 1) + pCmd->wStateCount);
  1182. break;
  1183. case D3DDP2OP_SETVERTEXSHADER:
  1184. HR_RET(pStateSetFuncTbl->pfnDp2SetVertexShader(this, pCmd));
  1185. // Update the command buffer pointer
  1186. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1187. ((D3DHAL_DP2VERTEXSHADER *)(pCmd + 1) + pCmd->wStateCount);
  1188. break;
  1189. case D3DDP2OP_SETVERTEXSHADERCONST:
  1190. {
  1191. LPD3DHAL_DP2SETVERTEXSHADERCONST pSVC =
  1192. (LPD3DHAL_DP2SETVERTEXSHADERCONST)(pCmd + 1);
  1193. WORD i;
  1194. for( i = 0; i < pCmd->wStateCount ; i++ )
  1195. {
  1196. LPDWORD pData = (LPDWORD)(pSVC + 1);
  1197. hr = pStateSetFuncTbl->pfnDp2SetVertexShaderConsts(
  1198. this, pSVC->dwRegister, pSVC->dwCount, pData );
  1199. if( FAILED( hr ) ) break;
  1200. // Update the pointer
  1201. pSVC = (LPD3DHAL_DP2SETVERTEXSHADERCONST)((LPBYTE)pData +
  1202. pSVC->dwCount * 4 *
  1203. sizeof( float ) );
  1204. }
  1205. // Successful termination of the loop:
  1206. // Update the command buffer pointer
  1207. if( i == pCmd->wStateCount )
  1208. *ppCmd = (LPD3DHAL_DP2COMMAND)pSVC;
  1209. else
  1210. return hr;
  1211. break;
  1212. }
  1213. case D3DDP2OP_SETSTREAMSOURCE:
  1214. // This function also updates the ppCmd pointer
  1215. HR_RET(pStateSetFuncTbl->pfnDp2SetStreamSource(this, pCmd));
  1216. // Update the command buffer pointer
  1217. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1218. ((D3DHAL_DP2SETSTREAMSOURCE *)(pCmd + 1) + pCmd->wStateCount);
  1219. break;
  1220. case D3DDP2OP_SETSTREAMSOURCEUM:
  1221. // This function also updates the ppCmd pointer
  1222. HR_RET(Dp2SetStreamSourceUM( pCmd, pUMVtx ));
  1223. // Update the command buffer pointer
  1224. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1225. ((D3DHAL_DP2SETSTREAMSOURCEUM *)(pCmd + 1) + pCmd->wStateCount);
  1226. break;
  1227. case D3DDP2OP_SETINDICES:
  1228. // This function also updates the ppCmd pointer
  1229. HR_RET(pStateSetFuncTbl->pfnDp2SetIndices(this, pCmd));
  1230. // Update the command buffer pointer
  1231. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1232. ((D3DHAL_DP2SETINDICES *)(pCmd + 1) + pCmd->wStateCount);
  1233. break;
  1234. case D3DDP2OP_CREATEPIXELSHADER:
  1235. {
  1236. LPD3DHAL_DP2CREATEPIXELSHADER pCPS =
  1237. (LPD3DHAL_DP2CREATEPIXELSHADER)(pCmd + 1);
  1238. WORD i;
  1239. for( i = 0; i < pCmd->wStateCount ; i++ )
  1240. {
  1241. LPDWORD pCode = (LPDWORD)(pCPS + 1);
  1242. hr = Dp2CreatePixelShader( pCPS->dwHandle,
  1243. pCPS->dwCodeSize, pCode );
  1244. if( FAILED( hr ) ) break;
  1245. // Update the pointer
  1246. pCPS = (LPD3DHAL_DP2CREATEPIXELSHADER)((LPBYTE)pCode +
  1247. pCPS->dwCodeSize);
  1248. }
  1249. // Successful termination of the loop:
  1250. // Update the command buffer pointer
  1251. if( i == pCmd->wStateCount )
  1252. *ppCmd = (LPD3DHAL_DP2COMMAND)pCPS;
  1253. else
  1254. return hr;
  1255. break;
  1256. }
  1257. case D3DDP2OP_DELETEPIXELSHADER:
  1258. HR_RET(Dp2DeletePixelShader(pCmd));
  1259. // Update the command buffer pointer
  1260. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1261. ((D3DHAL_DP2PIXELSHADER *)(pCmd + 1) + pCmd->wStateCount);
  1262. break;
  1263. case D3DDP2OP_SETPIXELSHADER:
  1264. HR_RET(pStateSetFuncTbl->pfnDp2SetPixelShader(this, pCmd));
  1265. // Update the command buffer pointer
  1266. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1267. ((D3DHAL_DP2PIXELSHADER *)(pCmd + 1) + pCmd->wStateCount);
  1268. break;
  1269. case D3DDP2OP_SETPIXELSHADERCONST:
  1270. {
  1271. LPD3DHAL_DP2SETPIXELSHADERCONST pSVC =
  1272. (LPD3DHAL_DP2SETPIXELSHADERCONST)(pCmd + 1);
  1273. WORD i;
  1274. for( i = 0; i < pCmd->wStateCount ; i++ )
  1275. {
  1276. LPDWORD pData = (LPDWORD)(pSVC + 1);
  1277. hr = pStateSetFuncTbl->pfnDp2SetPixelShaderConsts(
  1278. this, pSVC->dwRegister, pSVC->dwCount, pData );
  1279. if( FAILED( hr ) ) break;
  1280. // Update the pointer
  1281. pSVC = (LPD3DHAL_DP2SETPIXELSHADERCONST)((LPBYTE)pData +
  1282. pSVC->dwCount * 4 *
  1283. sizeof( float ) );
  1284. }
  1285. // Successful termination of the loop:
  1286. // Update the command buffer pointer
  1287. if( i == pCmd->wStateCount )
  1288. *ppCmd = (LPD3DHAL_DP2COMMAND)pSVC;
  1289. else
  1290. return hr;
  1291. break;
  1292. }
  1293. case D3DDP2OP_SETPALETTE:
  1294. {
  1295. HR_RET(Dp2SetPalette(pCmd));
  1296. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1297. ((D3DHAL_DP2SETPALETTE *)(pCmd + 1) + pCmd->wStateCount);
  1298. break;
  1299. }
  1300. case D3DDP2OP_UPDATEPALETTE:
  1301. {
  1302. LPD3DHAL_DP2UPDATEPALETTE pUP = (LPD3DHAL_DP2UPDATEPALETTE)(pCmd + 1);
  1303. WORD i;
  1304. for( i = 0; i < pCmd->wStateCount ; i++ )
  1305. {
  1306. PALETTEENTRY* pEntries = (PALETTEENTRY *)(pUP + 1);
  1307. HR_RET(Dp2UpdatePalette(pUP, pEntries));
  1308. pUP = (LPD3DHAL_DP2UPDATEPALETTE)(pEntries + pUP->wNumEntries);
  1309. }
  1310. if( i == pCmd->wStateCount )
  1311. *ppCmd = (LPD3DHAL_DP2COMMAND)pUP;
  1312. else
  1313. return hr;
  1314. break;
  1315. }
  1316. case D3DDP2OP_SETTEXLOD:
  1317. {
  1318. HR_RET(Dp2SetTexLod(pCmd));
  1319. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1320. ((D3DHAL_DP2SETTEXLOD *)(pCmd + 1) + pCmd->wStateCount);
  1321. break;
  1322. }
  1323. case D3DDP2OP_SETPRIORITY:
  1324. {
  1325. // Skip these tokens. RefDev doesnt need to handle SetPriority
  1326. *ppCmd = (LPD3DHAL_DP2COMMAND)
  1327. ((D3DHAL_DP2SETPRIORITY *)(pCmd + 1) + pCmd->wStateCount);
  1328. break;
  1329. }
  1330. case D3DDP2OP_TEXBLT:
  1331. {
  1332. LPD3DHAL_DP2TEXBLT pTB = (LPD3DHAL_DP2TEXBLT)(pCmd + 1);
  1333. for( WORD i = 0; i < pCmd->wStateCount ; i++ )
  1334. {
  1335. if( pTB->dwDDDestSurface == 0 )
  1336. {
  1337. // This is a PreLoad command, ignore it since
  1338. // RefDev just fakes driver management.
  1339. }
  1340. else
  1341. {
  1342. DPFERR( "TEXBLT not supported by RefDev\n" );
  1343. }
  1344. pTB++;
  1345. }
  1346. *ppCmd = (LPD3DHAL_DP2COMMAND)pTB;
  1347. break;
  1348. }
  1349. case D3DDP2OP_BUFFERBLT:
  1350. {
  1351. LPD3DHAL_DP2BUFFERBLT pBB = (LPD3DHAL_DP2BUFFERBLT)(pCmd + 1);
  1352. for( WORD i = 0; i < pCmd->wStateCount ; i++ )
  1353. {
  1354. if( pBB->dwDDDestSurface == 0 )
  1355. {
  1356. // This is a PreLoad command, ignore it since
  1357. // RefDev just fakes driver management.
  1358. }
  1359. else
  1360. {
  1361. DPFERR( "BUFFERBLT not supported by RefDev\n" );
  1362. }
  1363. pBB++;
  1364. }
  1365. *ppCmd = (LPD3DHAL_DP2COMMAND)pBB;
  1366. break;
  1367. }
  1368. case D3DDP2OP_VOLUMEBLT:
  1369. {
  1370. LPD3DHAL_DP2VOLUMEBLT pVB = (LPD3DHAL_DP2VOLUMEBLT)(pCmd + 1);
  1371. for( WORD i = 0; i < pCmd->wStateCount ; i++ )
  1372. {
  1373. if( pVB->dwDDDestSurface == 0 )
  1374. {
  1375. // This is a PreLoad command, ignore it since
  1376. // RefDev just fakes driver management.
  1377. }
  1378. else
  1379. {
  1380. DPFERR( "VOLUMEBLT not supported by RefDev\n" );
  1381. }
  1382. pVB++;
  1383. }
  1384. *ppCmd = (LPD3DHAL_DP2COMMAND)pVB;
  1385. break;
  1386. }
  1387. case D3DOP_MATRIXLOAD:
  1388. {
  1389. DPFERR( "MATRIXLOAD not supported by RefDev\n" );
  1390. hr = D3DERR_COMMAND_UNPARSED;
  1391. break;
  1392. }
  1393. case D3DOP_MATRIXMULTIPLY:
  1394. {
  1395. DPFERR( "MATRIXMULTIPLY not supported by RefDev\n" );
  1396. hr = D3DERR_COMMAND_UNPARSED;
  1397. break;
  1398. }
  1399. case D3DOP_STATETRANSFORM:
  1400. {
  1401. DPFERR( "STATETRANSFORM not supported by RefDev\n" );
  1402. hr = D3DERR_COMMAND_UNPARSED;
  1403. break;
  1404. }
  1405. case D3DOP_STATELIGHT:
  1406. {
  1407. DPFERR( "STATELIGHT not supported by RefDev\n" );
  1408. hr = D3DERR_COMMAND_UNPARSED;
  1409. break;
  1410. }
  1411. case D3DOP_TEXTURELOAD:
  1412. {
  1413. DPFERR( "TEXTURELOAD not supported by RefDev\n" );
  1414. hr = D3DERR_COMMAND_UNPARSED;
  1415. break;
  1416. }
  1417. case D3DOP_BRANCHFORWARD:
  1418. {
  1419. DPFERR( "BRANCHFORWARD not supported by RefDev\n" );
  1420. hr = D3DERR_COMMAND_UNPARSED;
  1421. break;
  1422. }
  1423. case D3DOP_SETSTATUS:
  1424. {
  1425. DPFERR( "SETSTATUS not supported by RefDev\n" );
  1426. hr = D3DERR_COMMAND_UNPARSED;
  1427. break;
  1428. }
  1429. case D3DOP_EXIT:
  1430. {
  1431. DPFERR( "EXIT not supported by RefDev\n" );
  1432. hr = D3DERR_COMMAND_UNPARSED;
  1433. break;
  1434. }
  1435. case D3DOP_PROCESSVERTICES:
  1436. {
  1437. DPFERR( "PROCESSVERTICES not supported by RefDev\n" );
  1438. hr = D3DERR_COMMAND_UNPARSED;
  1439. break;
  1440. }
  1441. default:
  1442. DPFERR( "Unknown command encountered" );
  1443. return E_FAIL;
  1444. }
  1445. return hr;
  1446. }
  1447. #endif //__D3D_NULL_REF