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.

825 lines
28 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // d3dif.hpp
  4. //
  5. // D3D front-end/rasterizer interface header.
  6. //
  7. // Copyright (C) Microsoft Corporation, 1997.
  8. //
  9. //----------------------------------------------------------------------------
  10. #ifndef _D3DIF_HPP_
  11. #define _D3DIF_HPP_
  12. #include <setup.hpp>
  13. // For Primitive function prototypes.
  14. #include <pmfns_mh.h>
  15. // Vertex data is aligned on 32-byte boundaries.
  16. #define DP_VTX_ALIGN 32
  17. // Flags for uflags of D3DContex
  18. #define D3DCONTEXT_IN_BEGIN 0x0001
  19. #define D3DCONTEXT_TEXTURE_LOCKED 0x0002
  20. // Flags for D3DDEVICEDESC dwDeviceZBufferBitDepth
  21. // Note: This must be replicated in ddraw\ddd3dapi.h so DDHEL can pick them up
  22. // It only affect what legacy apps see when using GetCaps or EnumDevices,
  23. // internally ZBufferFormats() is checked when on ZBuffer creation.
  24. // Note stencil formats should have no representation in this flag word
  25. // becase legacy apps will be fooled into trying to create a Z-only surface
  26. // at the DDBD bitdepth and fail. New apps should ignore dwDeviceZBufferBitDepth
  27. // and use EnumZBufferFormats
  28. #define D3DSWRASTERIZER_ZBUFFERBITDEPTHFLAGS (DDBD_16)
  29. // Macros used to access DDRAW surface info.
  30. #define DDSurf_Width(lpLcl) ( (lpLcl)->lpGbl->wWidth )
  31. #define DDSurf_Pitch(lpLcl) ( (lpLcl)->lpGbl->lPitch )
  32. #define DDSurf_Height(lpLcl) ( (lpLcl)->lpGbl->wHeight )
  33. #define DDSurf_BitDepth(lpLcl) \
  34. ( (lpLcl->dwFlags & DDRAWISURF_HASPIXELFORMAT) ? \
  35. (lpLcl->lpGbl->ddpfSurface.dwRGBBitCount) : \
  36. (lpLcl->lpGbl->lpDD->vmiData.ddpfDisplay.dwRGBBitCount) \
  37. )
  38. #define DDSurf_PixFmt(lpLcl) \
  39. ( ((lpLcl)->dwFlags & DDRAWISURF_HASPIXELFORMAT) ? \
  40. ((lpLcl)->lpGbl->ddpfSurface) : \
  41. ((lpLcl)->lpGbl->lpDD->vmiData.ddpfDisplay) \
  42. )
  43. #define VIDEO_MEMORY(pDDS) \
  44. (!(((LPDDRAWI_DDRAWSURFACE_INT) (pDDS))->lpLcl->lpGbl->dwGlobalFlags & \
  45. DDRAWISURFGBL_SYSMEMREQUESTED))
  46. #define SURFACE_LOCKED(pDDS) \
  47. (((LPDDRAWI_DDRAWSURFACE_INT)(pDDS))->lpLcl->lpGbl->dwUsageCount > 0)
  48. // Macro to retrieve SPANTEX pointer
  49. #define HANDLE_TO_SPANTEX(hTex) \
  50. (*(PD3DI_SPANTEX *)ULongToPtr(hTex))
  51. // Check the return value and return if something wrong.
  52. // Assume hr has been declared
  53. #define HR_RET(exp) \
  54. { \
  55. hr = (exp); \
  56. if (hr != D3D_OK) \
  57. { \
  58. return hr; \
  59. } \
  60. }
  61. // Triangle/Line/Point function
  62. #define PFN_TRIANGLE_5ARG_DEFAULT (D3DTRIFLAG_EDGEENABLE1 | \
  63. D3DTRIFLAG_EDGEENABLE2 | \
  64. D3DTRIFLAG_EDGEENABLE3)
  65. typedef HRESULT (*PFN_TRIANGLE)(LPVOID pCtx, PUINT8 pV0, PUINT8 pV1,
  66. PUINT8 pV2,
  67. WORD wFlags /*= PFN_TRIANGLE_5ARG_DEFAULT*/);
  68. typedef HRESULT (*PFN_POINT)(LPVOID pCtx, PUINT8 pV0);
  69. typedef HRESULT (*PFN_LINE)(LPVOID pCtx, PUINT8 pV0, PUINT8 pV1);
  70. typedef void (*PFN_STORELASTPIXELSTATE)(LPVOID pCtx, BOOL bStore);
  71. typedef HRESULT (*PFN_DP2SETRENDERSTATES)(LPVOID pCtx,
  72. DWORD dwFvf,
  73. LPD3DHAL_DP2COMMAND pCmd,
  74. LPDWORD lpdwRuntimeRStates);
  75. typedef HRESULT (*PFN_DP2TEXTURESTAGESTATE)(LPVOID pCtx,
  76. DWORD dwFvf,
  77. LPD3DHAL_DP2COMMAND pCmd);
  78. typedef HRESULT (*PFN_DP2SETVIEWPORT)(LPVOID pCtx, LPD3DHAL_DP2COMMAND pCmd);
  79. typedef HRESULT (*PFN_DP2SETWRANGE)(LPVOID pCtx, LPD3DHAL_DP2COMMAND pCmd);
  80. typedef struct _PRIMITIVE_FUNTIONS
  81. {
  82. PFN_TRIANGLE pfnTri;
  83. PFN_POINT pfnPoint;
  84. PFN_LINE pfnLine;
  85. PFN_STORELASTPIXELSTATE pfnStoreLastPixelState;
  86. PFN_DP2SETRENDERSTATES pfnDp2SetRenderStates;
  87. PFN_DP2TEXTURESTAGESTATE pfnDp2TextureStageState;
  88. PFN_DP2SETVIEWPORT pfnDp2SetViewport;
  89. PFN_DP2SETWRANGE pfnDp2SetWRange;
  90. }PRIMITIVE_FUNTIONS;
  91. typedef enum _SW_RAST_TYPE
  92. {
  93. SW_RAST_REFNULL = 1,
  94. SW_RAST_RGB = 2,
  95. SW_RAST_MMX = 3,
  96. SW_RAST_MMXASRGB = 4,
  97. }SW_RAST_TYPE;
  98. // Records the stride and the member offsets of the current FVF vertex type
  99. // Used to pack a FVF vertex into one known by the rasterizer, such as
  100. // RAST_GENERIC_VERTEX
  101. typedef struct _FVFDATA
  102. {
  103. // 0 means no according field
  104. INT16 offsetRHW;
  105. INT16 offsetDiff;
  106. INT16 offsetSpec;
  107. INT16 offsetTex0;
  108. INT16 offsetTex1;
  109. UINT16 stride;
  110. RAST_VERTEX_TYPE vtxType;
  111. DWORD preFVF;
  112. INT TexIdx[2];
  113. UINT cActTex;
  114. }FVFDATA;
  115. // Class used for the context returned to D3DIM.
  116. class D3DContext
  117. {
  118. public:
  119. D3DI_RASTCTX m_RastCtx;
  120. // InBegin and TextureLockd flags
  121. // TextureLockd bit is set/cleared by texture Lock/Unlock functions.
  122. // It is used by texture Lock/Unlock and Begin functions.
  123. // InBegin bit is set by Begin and cleared by End
  124. unsigned short m_uFlags;
  125. // This is init'ed according to the fill mode.
  126. // It is init'ed after state change and before rendering
  127. PRIMITIVE_FUNTIONS m_fnPrims;
  128. // This is used to save the current ramp tex map in Begin and then used to
  129. // restore it in End. It's needed primarily because for ExecBuf apps the
  130. // the current mat may not be the one used for a primitive. For DrawPrim
  131. // apps, the prims are flushed whenever a material change occurs. As a
  132. // result this is not necessary but will not hurt anything. Also, if
  133. // everything works out fine, the Flush may be removed.
  134. PUINT32 pTexRampmapSave;
  135. // Used to store the old last pixel setting when drawing line strips.
  136. UINT uOldFlags;
  137. inline BOOL IsTextureOff(void);
  138. inline void UpdatePrimFunctionTbl(void); // Init m_pfnTri
  139. inline BOOL IsAnyStatesChanged(void);
  140. inline BOOL IsStateChanged(UINT32 uState);
  141. inline void StateChanged(UINT32 uState);
  142. inline void SetAllStatesDirtyBits(void);
  143. inline void ClearAllStatesDirtyBits(void);
  144. inline void ClearStateDirtyBit(UINT32 uState);
  145. // FVF stuff
  146. FVFDATA m_fvfData;
  147. #if DBG
  148. inline HRESULT ValidatePrimType(D3DPRIMITIVETYPE PrimitiveType);
  149. #endif
  150. PrimProcessor m_PrimProc;
  151. // Used by RenderState for override states.
  152. D3DFE_STATESET m_renderstate_override;
  153. UINT32 dwSize;
  154. D3DContext(void){};
  155. ~D3DContext(void){};
  156. HRESULT Initialize(LPDIRECTDRAWSURFACE pDDS,
  157. LPDIRECTDRAWSURFACE pDDSZ, DWORD BeadSet, DWORD devVer);
  158. HRESULT FillContext(LPDIRECTDRAWSURFACE pDDS, LPDIRECTDRAWSURFACE pDDSZ);
  159. HRESULT SetViewport(LPD3DHAL_DP2VIEWPORTINFO pVpt);
  160. HRESULT TextureSetState(PD3DI_SPANTEX pSpanTex, DWORD dwState, DWORD dwValue);
  161. HRESULT ValidateTextureStageState(void);
  162. HRESULT UpdateActiveTexStageCount(void);
  163. inline PD3DI_RASTCTX GetRastCtx(void){return &m_RastCtx;};
  164. HRESULT Begin(void);
  165. inline HRESULT End(BOOL bNotFlush = TRUE);
  166. inline void BeginPrimSet(D3DPRIMITIVETYPE PrimType, RAST_VERTEX_TYPE VertType)
  167. {m_PrimProc.BeginPrimSet(PrimType, VertType);};
  168. inline void StoreLastPixelState(BOOL bStore);
  169. inline PRIMITIVE_FUNTIONS *GetFunsTbl(void){return &m_fnPrims;};
  170. void RastUnlockSpanTexture(void);
  171. HRESULT RastLockSpanTexture(void);
  172. void UpdateColorKeyAndPalette(void);
  173. void RemoveTexture(PD3DI_SPANTEX pSpanTex);
  174. HRESULT InitSpanTexture(PD3DI_SPANTEX pSpanTex, LPDIRECTDRAWSURFACE pDDS);
  175. HRESULT SetSizesSpanTexture(PD3DI_SPANTEX pSpanTex);
  176. HRESULT SetRenderState(UINT32 uState, UINT32 uStateVal);
  177. HRESULT UpdateRenderStates(LPDWORD puStateChange, UINT cStateChanges);
  178. HRESULT UpdateAllRenderStates(LPDWORD puStates);
  179. HRESULT Dp2SetRenderStates(LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates);
  180. HRESULT Dp2TextureStageState(LPD3DHAL_DP2COMMAND pCmd, DWORD dwFvf);
  181. void MapTextureStage0State( void );
  182. void MapTextureStage1State( void );
  183. void MapLegacyTextureBlend( void );
  184. void MapLegacyTextureFilter( void );
  185. inline HRESULT CheckDrawOnePrimitive(
  186. LPD3DHAL_DRAWONEPRIMITIVEDATA pOnePrimData);
  187. inline HRESULT CheckDrawOneIndexedPrimitive(
  188. LPD3DHAL_DRAWONEINDEXEDPRIMITIVEDATA pOneIdxPrimData);
  189. inline HRESULT DrawOnePrimitive(PUINT8 pVtx,
  190. D3DPRIMITIVETYPE PrimType,
  191. UINT cVertices);
  192. inline HRESULT DrawOneIndexedPrimitive(PUINT8 pVtx,
  193. LPWORD puIndices,
  194. D3DPRIMITIVETYPE PrimType,
  195. UINT cIndices);
  196. // Check if a triangle is culled or not. It's only used for wireframe and
  197. // point mode. It's done in PrimProc.Tri for solid mode.
  198. inline BOOL NotCulled(LPD3DTLVERTEX pV0, LPD3DTLVERTEX pV1,
  199. LPD3DTLVERTEX pV2);
  200. // FVF stuff
  201. HRESULT FASTCALL CheckFVF(DWORD dwFVF);
  202. void FASTCALL PackGenVertex(PUINT8 pFvfVtx, RAST_GENERIC_VERTEX *pGenVtx);
  203. inline UINT16 GetFvfStride(void){return m_fvfData.stride;};
  204. inline RAST_VERTEX_TYPE GetFvfVertexType(void){return m_fvfData.vtxType;};
  205. // Following functions are for RampRast
  206. // Create/Destroy a RampLightingDriver.
  207. inline HRESULT CreateRampLightingDriver(void);
  208. inline void DestroyRampLightingDriver(void);
  209. inline void InitRampFuncs(void){
  210. m_fnPrims.pfnTri = RAMP_TriSolid;
  211. m_fnPrims.pfnPoint = RAMP_Point;
  212. m_fnPrims.pfnLine = RAMP_Line;
  213. };
  214. inline HRESULT RampCreateMaterial(D3DMATERIALHANDLE hMat);
  215. inline HRESULT RampDestroyMaterial(D3DMATERIALHANDLE hMat);
  216. inline HRESULT RampSetLightstate(UINT32 uState, LPVOID pVal);
  217. inline HRESULT RampMaterialChanged(D3DMATERIALHANDLE hMat);
  218. inline void BeginSceneHook(void);
  219. inline void EndSceneHook(void);
  220. inline HRESULT RampSceneCapture(DWORD dwStart, LPDIRECT3DDEVICEI lpDevI);
  221. inline HRESULT RampFindLightingRange(RAMP_RANGE_INFO *pRampInfo);
  222. inline HRESULT RampClear(void);
  223. inline HRESULT RampMaterialToPixel(D3DMATERIALHANDLE hMat, DWORD* pPixel);
  224. inline void RampSetFogData(UINT32 uState, UINT32 uStateVal);
  225. inline void RampSetMaterial(D3DMATERIALHANDLE hMat);
  226. inline HRESULT RampCheckTexMap(LPD3DTLVERTEX pV);
  227. inline void RampInitTexMap(LPD3DTLVERTEX pV)
  228. {m_RastCtx.pTexRampMap = (PUINT32)ULongToPtr(pV->specular);};
  229. inline void RampUpdateRangeInfo(void);
  230. inline HRESULT RGB8ColorToPixel(D3DCOLOR Color, DWORD* pdwPalIdx);
  231. inline HRESULT RampPaletteChanged(D3DTEXTUREHANDLE hTex);
  232. inline HRESULT RampClearTexRect(D3DMATERIALHANDLE hMat, LPD3DRECT pRect);
  233. };
  234. inline void D3DContext::StoreLastPixelState(BOOL bStore)
  235. {
  236. if (bStore)
  237. {
  238. uOldFlags = m_PrimProc.GetFlags();
  239. m_PrimProc.ClrFlags(PPF_DRAW_LAST_LINE_PIXEL);
  240. }
  241. else
  242. {
  243. m_PrimProc.SetFlags(uOldFlags & PPF_DRAW_LAST_LINE_PIXEL);
  244. }
  245. }
  246. inline BOOL D3DContext::NotCulled(LPD3DTLVERTEX pV0,
  247. LPD3DTLVERTEX pV1, LPD3DTLVERTEX pV2)
  248. {
  249. if (m_RastCtx.pdwRenderState[D3DRENDERSTATE_CULLMODE] == D3DCULL_NONE)
  250. {
  251. return TRUE;
  252. }
  253. FLOAT x1, y1, x2x1, x3x1, y2y1, y3y1, fDet;
  254. x1 = pV0->sx;
  255. y1 = pV0->sy;
  256. x2x1 = pV1->sx - x1;
  257. y2y1 = pV1->sy - y1;
  258. x3x1 = pV2->sx - x1;
  259. y3y1 = pV2->sy - y1;
  260. fDet = x2x1 * y3y1 - x3x1 * y2y1;
  261. if (0. == fDet)
  262. {
  263. return FALSE;
  264. }
  265. switch ( m_RastCtx.pdwRenderState[D3DRENDERSTATE_CULLMODE] )
  266. {
  267. case D3DCULL_CW:
  268. if ( fDet > 0.f )
  269. {
  270. return FALSE;
  271. }
  272. break;
  273. case D3DCULL_CCW:
  274. if ( fDet < 0.f )
  275. {
  276. return FALSE;
  277. }
  278. break;
  279. }
  280. return TRUE;
  281. }
  282. // Update m_pfnPrims according to the current fill mode, device type
  283. // and vertextype. It's called when fill mode or FVF type chang.
  284. inline void D3DContext::UpdatePrimFunctionTbl(void)
  285. {
  286. if (m_RastCtx.BeadSet == D3DIBS_RAMP)
  287. {
  288. switch (m_RastCtx.pdwRenderState[D3DRENDERSTATE_FILLMODE])
  289. {
  290. case D3DFILL_POINT:
  291. m_fnPrims.pfnTri = RAMP_TriPoint;
  292. break;
  293. case D3DFILL_WIREFRAME:
  294. m_fnPrims.pfnTri = RAMP_TriWireframe;
  295. break;
  296. case D3DFILL_SOLID:
  297. default:
  298. m_fnPrims.pfnTri = RAMP_TriSolid;
  299. break;
  300. }
  301. }
  302. else
  303. {
  304. if (m_fvfData.vtxType == RAST_GENVERTEX)
  305. {
  306. m_fnPrims.pfnPoint = RGB_PointPack;
  307. m_fnPrims.pfnLine = RGB_LinePack;
  308. }
  309. else
  310. {
  311. m_fnPrims.pfnPoint = RGB_PointNoPack;
  312. m_fnPrims.pfnLine = RGB_LineNoPack;
  313. }
  314. switch (m_RastCtx.pdwRenderState[D3DRENDERSTATE_FILLMODE])
  315. {
  316. case D3DFILL_POINT:
  317. if (m_fvfData.vtxType == RAST_GENVERTEX)
  318. {
  319. m_fnPrims.pfnTri = RGB_TriPackPoint;
  320. }
  321. else
  322. {
  323. m_fnPrims.pfnTri = RGB_TriNoPackPoint;
  324. }
  325. break;
  326. case D3DFILL_WIREFRAME:
  327. if (m_fvfData.vtxType == RAST_GENVERTEX)
  328. {
  329. m_fnPrims.pfnTri = RGB_TriPackWireframe;
  330. }
  331. else
  332. {
  333. m_fnPrims.pfnTri = RGB_TriNoPackWireframe;
  334. }
  335. break;
  336. break;
  337. case D3DFILL_SOLID:
  338. default:
  339. if (m_fvfData.vtxType == RAST_GENVERTEX)
  340. {
  341. m_fnPrims.pfnTri = RGB_TriPackSolid;
  342. }
  343. else
  344. {
  345. m_fnPrims.pfnTri = RGB_TriNoPackSolid;
  346. }
  347. break;
  348. }
  349. }
  350. }
  351. // The following inline functions are provided to manipulate StatesDirtyBits.
  352. // StatesDirtyBits is used to store one dirty bit for each render state. It
  353. // contains (D3DHAL_MAX_RSTATES_AND_STAGES>>3+1) bytes.
  354. // For a particular state, say uState,
  355. // it is represented by i'th bit of j'th byte, where i=(uState & 7) and
  356. // j=uState>>3. So,
  357. // StatesDirtyBits[uState>>3]&(1<<(uState&7)) gives the bit info. for uState
  358. // StatesDirtyBits[uState>>3] |= (1<<(uState&7)) sets the bit to 1
  359. // StatesDirtyBits[uState>>3] &= ~(1 <<(uState&7)) clears the bit to 0
  360. // Check if any render states have changed. The info. is stored in the bit
  361. // corresponding to D3DHAL_MAX_RSTATES_AND_STAGES.
  362. inline BOOL D3DContext::IsAnyStatesChanged()
  363. {
  364. return (m_RastCtx.StatesDirtyBits[D3DHAL_MAX_RSTATES_AND_STAGES>>3] &
  365. (1<<(D3DHAL_MAX_RSTATES_AND_STAGES & 7)));
  366. }
  367. // Check if uState has changed.
  368. inline BOOL D3DContext::IsStateChanged(UINT32 uState)
  369. {
  370. return (m_RastCtx.StatesDirtyBits[uState>>3] & (1<<(uState & 7)));
  371. };
  372. // uState has changed so set the according dirty bit and the AnyStates bit.
  373. inline void D3DContext::StateChanged(UINT32 uState)
  374. {
  375. m_RastCtx.StatesDirtyBits[uState>>3] |= (1<<(uState & 7));
  376. m_RastCtx.StatesDirtyBits[D3DHAL_MAX_RSTATES_AND_STAGES>>3] |=
  377. (1<<(D3DHAL_MAX_RSTATES_AND_STAGES & 7));
  378. };
  379. // Called after bead chooser to clear all the dirty bits.
  380. inline void D3DContext::ClearAllStatesDirtyBits(void)
  381. {
  382. memset(m_RastCtx.StatesDirtyBits, 0, sizeof(UINT8) * RAST_DIRTYBITS_SIZE);
  383. };
  384. // Called at context creation time to set all the dirty bits.
  385. inline void D3DContext::SetAllStatesDirtyBits(void)
  386. {
  387. memset(m_RastCtx.StatesDirtyBits, 7, sizeof(UINT8) * RAST_DIRTYBITS_SIZE);
  388. };
  389. // Clear the dirty bit corresponding to uState.
  390. inline void D3DContext::ClearStateDirtyBit(UINT32 uState)
  391. {
  392. m_RastCtx.StatesDirtyBits[uState>>3] &= ~(1 << (uState & 7));
  393. }
  394. inline BOOL D3DContext::IsTextureOff(void)
  395. {
  396. return
  397. (m_RastCtx.cActTex == 0 ||
  398. (m_RastCtx.cActTex == 1 && m_RastCtx.pTexture[0] == NULL) ||
  399. (m_RastCtx.cActTex == 2 &&
  400. (m_RastCtx.pTexture[0] == NULL ||
  401. m_RastCtx.pTexture[1] == NULL)));
  402. }
  403. extern "C" HRESULT WINAPI
  404. DDInternalLock( LPDDRAWI_DDRAWSURFACE_LCL this_lcl, LPVOID* lpBits );
  405. extern "C" HRESULT WINAPI
  406. DDInternalUnlock( LPDDRAWI_DDRAWSURFACE_LCL this_lcl );
  407. // Lock surfaces before rendering
  408. inline HRESULT LockSurface(LPDIRECTDRAWSURFACE pDDS, LPVOID *ppData)
  409. {
  410. if (pDDS)
  411. {
  412. if (!VIDEO_MEMORY(pDDS))
  413. {
  414. if (SURFACE_LOCKED(pDDS))
  415. return DDERR_SURFACEBUSY;
  416. *ppData = (LPVOID)SURFACE_MEMORY(pDDS);
  417. return DD_OK;
  418. }
  419. else
  420. {
  421. HRESULT ddrval;
  422. do
  423. {
  424. LPDDRAWI_DDRAWSURFACE_INT lpInt;
  425. lpInt = (LPDDRAWI_DDRAWSURFACE_INT) pDDS;
  426. ddrval = DDInternalLock(lpInt->lpLcl, ppData);
  427. } while (ddrval == DDERR_WASSTILLDRAWING);
  428. return ddrval;
  429. }
  430. }
  431. return DD_OK;
  432. }
  433. // Unlock surfaces after rendering
  434. inline void UnlockSurface(LPDIRECTDRAWSURFACE pDDS)
  435. {
  436. if (pDDS && VIDEO_MEMORY(pDDS))
  437. {
  438. LPDDRAWI_DDRAWSURFACE_INT lpInt;
  439. lpInt = (LPDDRAWI_DDRAWSURFACE_INT) pDDS;
  440. DDInternalUnlock(lpInt->lpLcl);
  441. }
  442. }
  443. // After rendering cleanup: flush primitive processor, unlock textures
  444. inline HRESULT
  445. D3DContext::End(BOOL bNotFlush)
  446. {
  447. if (m_uFlags & D3DCONTEXT_IN_BEGIN)
  448. {
  449. HRESULT hr = m_PrimProc.End();
  450. // Unlock texture if this is not called in the middle of drawPrims to
  451. // flush for possible state changes. In the 2nd case, let
  452. // SetRenderState to handle it.
  453. if (bNotFlush)
  454. {
  455. RastUnlockSpanTexture();
  456. }
  457. // Unlock surfaces
  458. UnlockSurface(m_RastCtx.pDDS);
  459. if (m_RastCtx.pDDSZ != NULL)
  460. {
  461. UnlockSurface(m_RastCtx.pDDSZ);
  462. }
  463. m_uFlags &= ~D3DCONTEXT_IN_BEGIN;
  464. if (m_RastCtx.pRampDrv)
  465. {
  466. m_RastCtx.pTexRampMap = pTexRampmapSave;
  467. }
  468. return (hr);
  469. }
  470. else
  471. {
  472. // In the case of DrawPrims being called just to set render states,
  473. // Begin is actually not called.
  474. return D3D_OK;
  475. }
  476. }
  477. inline HRESULT
  478. D3DContext::RampCheckTexMap(LPD3DTLVERTEX pV)
  479. {
  480. if (m_RastCtx.pTexRampMap != (PUINT32)ULongToPtr(pV->specular))
  481. {
  482. HRESULT hr;
  483. // Flush Prims
  484. HR_RET(End());
  485. HR_RET(Begin());
  486. m_RastCtx.pTexRampMap = (PUINT32)ULongToPtr(pV->specular);
  487. }
  488. return D3D_OK;
  489. }
  490. // Following primitive functions are shared by RGB/RAMP/REF rasterizers
  491. HRESULT FASTCALL
  492. DoDrawOneIndexedPrimitive(LPVOID pCtx,
  493. PRIMITIVE_FUNTIONS *pfnPrims,
  494. UINT16 FvfStride,
  495. PUINT8 pVtx,
  496. LPWORD puIndices,
  497. D3DPRIMITIVETYPE PrimType,
  498. UINT cIndices);
  499. HRESULT FASTCALL
  500. DoDrawOnePrimitive(LPVOID pCtx,
  501. PRIMITIVE_FUNTIONS *pfnPrims,
  502. UINT16 FvfStride,
  503. PUINT8 pVtx,
  504. D3DPRIMITIVETYPE PrimType,
  505. UINT cVertices);
  506. HRESULT FASTCALL
  507. DoDrawOneEdgeFlagTriangleFan(LPVOID pCtx,
  508. PRIMITIVE_FUNTIONS *pfnPrims,
  509. UINT16 FvfStride,
  510. PUINT8 pVtx,
  511. UINT cVertices,
  512. UINT32 dwEdgeFlags);
  513. HRESULT FASTCALL
  514. DoRendPoints(LPVOID pCtx,
  515. PRIMITIVE_FUNTIONS *pfnPrims,
  516. LPD3DINSTRUCTION pIns,
  517. LPD3DTLVERTEX pVtx,
  518. LPD3DPOINT pPt);
  519. HRESULT FASTCALL
  520. DoRendLines(LPVOID pCtx,
  521. PRIMITIVE_FUNTIONS *pfnPrims,
  522. LPD3DINSTRUCTION pIns,
  523. LPD3DTLVERTEX pVtx,
  524. LPD3DLINE pLine);
  525. HRESULT FASTCALL
  526. DoRendTriangles(LPVOID pCtx,
  527. PRIMITIVE_FUNTIONS *pfnPrims,
  528. LPD3DINSTRUCTION pIns,
  529. LPD3DTLVERTEX pVtx,
  530. LPD3DTRIANGLE pTri);
  531. HRESULT FASTCALL
  532. DoDrawPrimitives2(LPVOID pCtx,
  533. PRIMITIVE_FUNTIONS *pfnPrims,
  534. UINT16 dwStride,
  535. DWORD dwFvf,
  536. PUINT8 pVtx,
  537. LPD3DHAL_DP2COMMAND *ppCmd,
  538. LPDWORD lpdwRStates,
  539. BOOL bWireframe = FALSE
  540. );
  541. inline HRESULT
  542. D3DContext::DrawOnePrimitive(PUINT8 pVtx,
  543. D3DPRIMITIVETYPE PrimType,
  544. UINT cVertices)
  545. {
  546. m_PrimProc.BeginPrimSet(PrimType, m_fvfData.vtxType);
  547. return DoDrawOnePrimitive((LPVOID)this,
  548. &m_fnPrims,
  549. m_fvfData.stride,
  550. (PUINT8)pVtx,
  551. PrimType,
  552. cVertices);
  553. }
  554. inline HRESULT
  555. D3DContext::DrawOneIndexedPrimitive(PUINT8 pVtx,
  556. LPWORD puIndices,
  557. D3DPRIMITIVETYPE PrimType,
  558. UINT cIndices)
  559. {
  560. m_PrimProc.BeginPrimSet(PrimType, m_fvfData.vtxType);
  561. return DoDrawOneIndexedPrimitive((LPVOID)this,
  562. &m_fnPrims,
  563. m_fvfData.stride,
  564. (PUINT8)pVtx,
  565. puIndices,
  566. PrimType,
  567. cIndices);
  568. }
  569. // Macros to check if a pointer is valid
  570. #if DBG
  571. #define VALID_D3DCONTEX_PTR(pDCtx) ((pDCtx)->dwSize == sizeof(D3DContext))
  572. #define VALID_D3DI_RASTCTX_PTR(pRastCtx) \
  573. ((pRastCtx)->dwSize == sizeof(D3DI_RASTCTX))
  574. #define VALID_D3DI_SPANTEX_PTR(pSpanTex) \
  575. ((pSpanTex)->dwSize == sizeof(D3DI_SPANTEX))
  576. #define VALID_D3DI_SPANTEX_PTR_PTR(ppSpanTex) \
  577. ((ppSpanTex) && VALID_D3DI_SPANTEX_PTR(*(ppSpanTex)))
  578. // Validate context. pCtx should be declared before this macro
  579. // Type can be D3DContext or RefRast
  580. #define VALIDATE_CONTEXT(caller_name, data_ptr, pCtx, type) \
  581. { \
  582. if ((data_ptr) == NULL) \
  583. { \
  584. D3D_INFO(1, "in %s, data pointer = NULL", (caller_name)); \
  585. return DDHAL_DRIVER_HANDLED; \
  586. } \
  587. pCtx = (type)((data_ptr)->dwhContext); \
  588. if (!pCtx) \
  589. { \
  590. D3D_INFO(1, "in %s, dwhContext = NULL", (caller_name)); \
  591. (data_ptr)->ddrval = D3DHAL_CONTEXT_BAD; \
  592. return DDHAL_DRIVER_HANDLED; \
  593. } \
  594. }
  595. #else // !DBG
  596. #define VALID_D3DCONTEX_PTR(pDCtx) 1
  597. #define VALID_D3DI_RASTCTX_PTR(pRastCtx) 1
  598. #define VALID_D3DI_SPANTEX_PTR(pSpanTex) 1
  599. #define VALID_D3DI_SPANTEX_PTR_PTR(ppSpanTex) 1
  600. // Validate context. pCtx should be declared before this macro
  601. // Type can be D3DContext or RefRast
  602. #define VALIDATE_CONTEXT(caller_name, data_ptr, pCtx, type) \
  603. { \
  604. pCtx = (type)((data_ptr)->dwhContext); \
  605. }
  606. #endif // !DBG
  607. // Validate D3DCxt. pDCtx should be declared before this macro
  608. #define VALIDATE_D3DCONTEXT(caller_name, data_ptr) \
  609. { \
  610. VALIDATE_CONTEXT(caller_name, data_ptr, pDCtx, D3DContext*); \
  611. if (!VALID_D3DCONTEX_PTR(pDCtx) || \
  612. !VALID_D3DI_RASTCTX_PTR((pDCtx)->GetRastCtx())) \
  613. { \
  614. D3D_INFO(1, "in %s, invalid dwhContext", (caller_name)); \
  615. (data_ptr)->ddrval = D3DHAL_CONTEXT_BAD; \
  616. return DDHAL_DRIVER_HANDLED; \
  617. } \
  618. }
  619. // Validate ReferenceRasterizer. pRefRast should be declared before this macro
  620. #define VALIDATE_REFRAST_CONTEXT(caller_name, data_ptr) \
  621. { \
  622. VALIDATE_CONTEXT(caller_name, data_ptr, pRefRast, ReferenceRasterizer*);\
  623. }
  624. #define CHECK_FVF(ret, pDCtx, dwFlags) \
  625. { \
  626. if ((ret = pDCtx->CheckFVF(dwFlags)) != DD_OK) \
  627. { \
  628. return DDHAL_DRIVER_HANDLED; \
  629. } \
  630. }
  631. HRESULT FASTCALL
  632. FindOutSurfFormat(LPDDPIXELFORMAT pDdPixFmt,
  633. D3DI_SPANTEX_FORMAT *pFmt);
  634. extern int
  635. TextureFormats(LPDDSURFACEDESC* lplpddsd, DWORD dwVersion, SW_RAST_TYPE RastType);
  636. extern int
  637. RampTextureFormats(LPDDSURFACEDESC* lplpddsd);
  638. extern int
  639. ZBufferFormats(DDPIXELFORMAT** ppDDPF, BOOL bIsRefRast);
  640. extern int
  641. RampZBufferFormats(DDPIXELFORMAT** ppDDPF);
  642. BOOL FASTCALL
  643. ValidTextureSize(INT16 iuSize, INT16 iuShift,
  644. INT16 ivSize, INT16 ivShift);
  645. BOOL FASTCALL
  646. ValidMipmapSize(INT16 iPreSize, INT16 iSize);
  647. DWORD __stdcall
  648. RastContextCreate(LPD3DHAL_CONTEXTCREATEDATA pCtxData, DWORD BeadSet);
  649. DWORD __stdcall
  650. RastContextCreate(LPD3DHAL_CONTEXTCREATEDATA pCtxData, DWORD BeadSet);
  651. DWORD __stdcall
  652. RastContextCreateC(LPD3DHAL_CONTEXTCREATEDATA pCtxData);
  653. DWORD __stdcall
  654. RastContextCreateCMMX(LPD3DHAL_CONTEXTCREATEDATA pCtxData);
  655. DWORD __stdcall
  656. RastContextCreateMMX(LPD3DHAL_CONTEXTCREATEDATA pCtxData);
  657. DWORD __stdcall
  658. RastContextCreateMMXAsRGB(LPD3DHAL_CONTEXTCREATEDATA pCtxData);
  659. DWORD __stdcall
  660. RastContextCreateRamp(LPD3DHAL_CONTEXTCREATEDATA pCtxData);
  661. DWORD __stdcall
  662. RastContextDestroy(LPD3DHAL_CONTEXTDESTROYDATA pCtxDestroyData);
  663. DWORD __stdcall
  664. RastContextDestroyRamp(LPD3DHAL_CONTEXTDESTROYDATA pCtxDestroyData);
  665. DWORD __stdcall
  666. RastSetRenderTarget(LPD3DHAL_SETRENDERTARGETDATA pTgtData);
  667. DWORD __stdcall
  668. RastTextureCreate(LPD3DHAL_TEXTURECREATEDATA pTexData);
  669. DWORD __stdcall
  670. RastTextureDestroy(LPD3DHAL_TEXTUREDESTROYDATA pTexDestroyData);
  671. DWORD __stdcall
  672. RastTextureSwap(LPD3DHAL_TEXTURESWAPDATA pTexSwapData);
  673. DWORD __stdcall
  674. RastTextureGetSurf(LPD3DHAL_TEXTUREGETSURFDATA pTexGetSurf);
  675. DWORD __stdcall
  676. RastRenderState(LPD3DHAL_RENDERSTATEDATA pStateData);
  677. DWORD __stdcall
  678. RastRenderPrimitive(LPD3DHAL_RENDERPRIMITIVEDATA pRenderData);
  679. DWORD __stdcall
  680. RastDrawOnePrimitive(LPD3DHAL_DRAWONEPRIMITIVEDATA pOnePrimData);
  681. DWORD __stdcall
  682. RastDrawOneIndexedPrimitive(LPD3DHAL_DRAWONEINDEXEDPRIMITIVEDATA
  683. pOneIdxPrimData);
  684. DWORD __stdcall
  685. RastDrawPrimitives(LPD3DHAL_DRAWPRIMITIVESDATA pDrawPrimData);
  686. DWORD __stdcall
  687. RastClearRamp(LPD3DHAL_CLEARDATA pClrData);
  688. DWORD __stdcall
  689. RastSceneCaptureRamp(LPD3DHAL_SCENECAPTUREDATA pSceneData);
  690. DWORD __stdcall
  691. RastValidateTextureStageState(LPD3DHAL_VALIDATETEXTURESTAGESTATEDATA pData);
  692. DWORD __stdcall
  693. RastDrawPrimitives2(LPD3DHAL_DRAWPRIMITIVES2DATA pDPrim2Data);
  694. DWORD __stdcall
  695. RefRastDrawPrimitives2(LPD3DHAL_DRAWPRIMITIVES2DATA pDPrim2Data);
  696. //---------------------------------------------------------------------------
  697. //
  698. // Interface for Reference Device External DLL
  699. //
  700. // prototypes for functions exported by d3dref.dll
  701. STDAPI GetRefHalProvider(REFCLSID riid, IHalProvider **ppHalProvider, HINSTANCE *phDll);
  702. STDAPI GetRefZBufferFormats(REFCLSID riid, DDPIXELFORMAT **ppDDPF);
  703. STDAPI GetRefTextureFormats(REFCLSID riid, LPDDSURFACEDESC* lplpddsd, DWORD dwD3DDeviceVersion);
  704. typedef HRESULT (STDAPICALLTYPE* PFNGETREFHALPROVIDER)(REFCLSID,IHalProvider**,HINSTANCE*);
  705. typedef HRESULT (STDAPICALLTYPE* PFNGETREFZBUFFERFORMATS)(REFCLSID, DDPIXELFORMAT**);
  706. typedef HRESULT (STDAPICALLTYPE* PFNGETREFTEXTUREFORMATS)(REFCLSID, LPDDSURFACEDESC*, DWORD);
  707. inline FARPROC LoadReferenceDeviceProc( char* szProc )
  708. {
  709. HINSTANCE hRefDLL;
  710. if (NULL == (hRefDLL = LoadLibrary("d3dref.dll")) )
  711. {
  712. return NULL;
  713. }
  714. return GetProcAddress(hRefDLL, szProc);
  715. }
  716. //---------------------------------------------------------------------------
  717. #endif // #ifndef _D3DIF_HPP_