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.

4265 lines
131 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: mcdcx.c
  3. *
  4. * GenMcdXXX layer between generic software implementation and MCD functions.
  5. *
  6. * Created: 05-Feb-1996 21:37:33
  7. * Author: Gilman Wong [gilmanw]
  8. *
  9. * Copyright (c) 1995 Microsoft Corporation
  10. *
  11. \**************************************************************************/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #ifdef _MCD_
  15. /******************************Public*Routine******************************\
  16. * bInitMcd
  17. *
  18. * Load MCD32.DLL and initialize the MCD api function table.
  19. *
  20. * History:
  21. * 11-Mar-1996 -by- Gilman Wong [gilmanw]
  22. * Wrote it.
  23. \**************************************************************************/
  24. MCDTABLE *gpMcdTable = (MCDTABLE *) NULL;
  25. MCDTABLE McdTable;
  26. MCDDRIVERINFOI McdDriverInfo;
  27. // Checks MCD version to see if the driver can accept direct buffer
  28. // access. Direct access was introduced in 1.1.
  29. #define SUPPORTS_DIRECT() \
  30. (McdDriverInfo.mcdDriverInfo.verMinor >= 0x10 || \
  31. McdDriverInfo.mcdDriverInfo.verMajor > 1)
  32. // Checks MCD version for 2.0 or greater
  33. #define SUPPORTS_20() \
  34. (McdDriverInfo.mcdDriverInfo.verMajor >= 2)
  35. static char *pszMcdEntryPoints[] = {
  36. "MCDGetDriverInfo",
  37. "MCDDescribeMcdPixelFormat",
  38. "MCDDescribePixelFormat",
  39. "MCDCreateContext",
  40. "MCDDeleteContext",
  41. "MCDAlloc",
  42. "MCDFree",
  43. "MCDBeginState",
  44. "MCDFlushState",
  45. "MCDAddState",
  46. "MCDAddStateStruct",
  47. "MCDSetViewport",
  48. "MCDSetScissorRect",
  49. "MCDQueryMemStatus",
  50. "MCDProcessBatch",
  51. "MCDReadSpan",
  52. "MCDWriteSpan",
  53. "MCDClear",
  54. "MCDSwap",
  55. "MCDGetBuffers",
  56. "MCDAllocBuffers",
  57. "MCDLock",
  58. "MCDUnlock",
  59. "MCDBindContext",
  60. "MCDSync",
  61. "MCDCreateTexture",
  62. "MCDDeleteTexture",
  63. "MCDUpdateSubTexture",
  64. "MCDUpdateTexturePalette",
  65. "MCDUpdateTexturePriority",
  66. "MCDUpdateTextureState",
  67. "MCDTextureStatus",
  68. "MCDTextureKey",
  69. "MCDDescribeMcdLayerPlane",
  70. "MCDDescribeLayerPlane",
  71. "MCDSetLayerPalette",
  72. "MCDDrawPixels",
  73. "MCDReadPixels",
  74. "MCDCopyPixels",
  75. "MCDPixelMap",
  76. "MCDDestroyWindow",
  77. "MCDGetTextureFormats",
  78. "MCDSwapMultiple",
  79. "MCDProcessBatch2"
  80. };
  81. #define NUM_MCD_ENTRY_POINTS (sizeof(pszMcdEntryPoints)/sizeof(char *))
  82. #define STR_MCD32_DLL "MCD32.DLL"
  83. BOOL FASTCALL bInitMcd(HDC hdc)
  84. {
  85. static BOOL bFirstTime = TRUE;
  86. ASSERTOPENGL(NUM_MCD_ENTRY_POINTS == sizeof(MCDTABLE)/sizeof(void *),
  87. "MCD entry points mismatch\n");
  88. //
  89. // Note on multi-threaded initialization.
  90. //
  91. // Since the table memory exists in global memory and the pointer to
  92. // the table is always set to point to this, it doesn't matter if multiple
  93. // thread attempt to run the initialization routine. The worse that
  94. // could happen is that we set the table multiple times.
  95. //
  96. if (bFirstTime && (gpMcdTable == (MCDTABLE *) NULL))
  97. {
  98. HMODULE hmod;
  99. PROC *ppfn;
  100. //
  101. // Attempt the load once and once only. Otherwise application
  102. // initialization time could be significantly slowed if MCD32.DLL
  103. // does not exist.
  104. //
  105. // We could have attempted this in the DLL entry point in responce
  106. // to PROCESS_ATTACH, but then we might end up wasting working set
  107. // if MCD is never used.
  108. //
  109. // So instead we control the load attempt with this static flag.
  110. //
  111. bFirstTime = FALSE;
  112. hmod = LoadLibraryA(STR_MCD32_DLL);
  113. if (hmod)
  114. {
  115. MCDTABLE McdTableLocal;
  116. BOOL bLoadFailed = FALSE;
  117. BOOL bDriverValid = FALSE;
  118. int i;
  119. //
  120. // Get address for each of the MCD entry points.
  121. //
  122. // To be multi-thread safe, we store the pointers in a local
  123. // table. Only after the *entire* table is successfully
  124. // initialized can we copy it to the global table.
  125. //
  126. ppfn = (PROC *) &McdTableLocal.pMCDGetDriverInfo;
  127. for (i = 0; i < NUM_MCD_ENTRY_POINTS; i++, ppfn++)
  128. {
  129. *ppfn = GetProcAddress(hmod, pszMcdEntryPoints[i]);
  130. if (!*ppfn)
  131. {
  132. WARNING1("bInitMcd: missing entry point %s\n", pszMcdEntryPoints[i]);
  133. bLoadFailed = TRUE;
  134. }
  135. }
  136. //
  137. // If all entry points successfully loaded, validate driver
  138. // by checking the MCDDRIVERINFO.
  139. //
  140. if (!bLoadFailed)
  141. {
  142. if ((McdTableLocal.pMCDGetDriverInfo)(hdc, &McdDriverInfo))
  143. {
  144. //
  145. // Validate MCD driver version, etc.
  146. //
  147. //!!!mcd -- what other types of validation can we do?
  148. #ifdef ALLOW_NEW_MCD
  149. if ((McdDriverInfo.mcdDriverInfo.verMajor == 1 &&
  150. (McdDriverInfo.mcdDriverInfo.verMinor == 0 ||
  151. McdDriverInfo.mcdDriverInfo.verMinor == 0x10)) ||
  152. (McdDriverInfo.mcdDriverInfo.verMajor == 2 &&
  153. McdDriverInfo.mcdDriverInfo.verMinor == 0))
  154. #else
  155. if (McdDriverInfo.mcdDriverInfo.verMajor == 1 &&
  156. McdDriverInfo.mcdDriverInfo.verMinor == 0)
  157. #endif
  158. {
  159. bDriverValid = TRUE;
  160. }
  161. else
  162. {
  163. WARNING("bInitMcd: bad version\n");
  164. }
  165. }
  166. }
  167. //
  168. // It is now safe to call MCD entry points via the table. Copy
  169. // local copy to the global table and set the global pointer.
  170. //
  171. if (bDriverValid)
  172. {
  173. McdTable = McdTableLocal;
  174. gpMcdTable = &McdTable;
  175. }
  176. else
  177. {
  178. WARNING1("bInitMcd: unloading %s\n", STR_MCD32_DLL);
  179. FreeLibrary(hmod);
  180. }
  181. }
  182. }
  183. return (gpMcdTable != (MCDTABLE *) NULL);
  184. }
  185. /******************************Public*Routine******************************\
  186. * vFlushDirtyState
  187. *
  188. * GENMCDSTATE maintains a set of dirty flags to track state changes.
  189. * This function updates the MCD driver state that is marked dirty.
  190. * The dirty flags are consequently cleared.
  191. *
  192. * History:
  193. * 07-Mar-1996 -by- Gilman Wong [gilmanw]
  194. * Wrote it.
  195. \**************************************************************************/
  196. VOID FASTCALL vFlushDirtyState(__GLGENcontext *gengc)
  197. {
  198. if (gengc->pMcdState)
  199. {
  200. //
  201. // Viewport, scissor, and texture each have separate update
  202. // functions/structures. Check the dirty flags and update
  203. // these first.
  204. //
  205. if (MCD_STATE_DIRTYTEST(gengc, VIEWPORT))
  206. {
  207. GenMcdViewport(gengc);
  208. MCD_STATE_CLEAR(gengc, VIEWPORT);
  209. }
  210. if (MCD_STATE_DIRTYTEST(gengc, SCISSOR))
  211. {
  212. GenMcdScissor(gengc);
  213. //
  214. // DO NOT CLEAR. Scissor is passed in two forms: a direct call
  215. // that affects clipping in MCDSRV32.DLL and a state call that
  216. // the MCD driver can optionally use for high performance h/w.
  217. // We need to leave the flag set so that the state call will
  218. // also be processed.
  219. //
  220. //MCD_STATE_CLEAR(gengc, SCISSOR);
  221. }
  222. if (MCD_STATE_DIRTYTEST(gengc, TEXTURE))
  223. {
  224. if (gengc->gc.texture.currentTexture)
  225. {
  226. __GLtextureObject *texobj;
  227. if (gengc->gc.state.enables.general & __GL_TEXTURE_2D_ENABLE)
  228. texobj = __glLookUpTextureObject(&gengc->gc, GL_TEXTURE_2D);
  229. else if (gengc->gc.state.enables.general & __GL_TEXTURE_1D_ENABLE)
  230. texobj = __glLookUpTextureObject(&gengc->gc, GL_TEXTURE_1D);
  231. else
  232. texobj = (__GLtextureObject *) NULL;
  233. if (texobj && texobj->loadKey)
  234. {
  235. ASSERTOPENGL(&texobj->texture.map == gengc->gc.texture.currentTexture,
  236. "vFlushDirtyState: texobj not current texture\n");
  237. GenMcdUpdateTextureState(gengc,
  238. &texobj->texture.map,
  239. texobj->loadKey);
  240. MCD_STATE_CLEAR(gengc, TEXTURE);
  241. }
  242. }
  243. }
  244. //
  245. // Take care of the other state.
  246. //
  247. if (MCD_STATE_DIRTYTEST(gengc, ALL))
  248. {
  249. //
  250. // Setup state command.
  251. //
  252. (gpMcdTable->pMCDBeginState)(&gengc->pMcdState->McdContext,
  253. gengc->pMcdState->McdCmdBatch.pv);
  254. //
  255. // Add MCDPIXELSTATE structure to state command if needed.
  256. //
  257. if (MCD_STATE_DIRTYTEST(gengc, PIXELSTATE))
  258. {
  259. GenMcdUpdatePixelState(gengc);
  260. }
  261. if (gengc->pMcdState->McdRcInfo.requestFlags &
  262. MCDRCINFO_FINE_GRAINED_STATE)
  263. {
  264. // Add front-end and rendering states.
  265. GenMcdUpdateFineState(gengc);
  266. }
  267. else
  268. {
  269. //
  270. // Add MCDRENDERSTATE structure to state command if needed.
  271. //
  272. if (MCD_STATE_DIRTYTEST(gengc, RENDERSTATE))
  273. {
  274. GenMcdUpdateRenderState(gengc);
  275. }
  276. }
  277. //
  278. // Add MCDSCISSORSTATE structure to state command if needed.
  279. //
  280. if (MCD_STATE_DIRTYTEST(gengc, SCISSOR))
  281. {
  282. GenMcdUpdateScissorState(gengc);
  283. }
  284. //
  285. // Add MCDTEXENVSTATE structure to state command if needed.
  286. //
  287. if (MCD_STATE_DIRTYTEST(gengc, TEXENV))
  288. {
  289. GenMcdUpdateTexEnvState(gengc);
  290. }
  291. //
  292. // Send state command to MCD driver.
  293. //
  294. (gpMcdTable->pMCDFlushState)(gengc->pMcdState->McdCmdBatch.pv);
  295. //
  296. // Clear dirty flags.
  297. //
  298. MCD_STATE_RESET(gengc);
  299. }
  300. }
  301. }
  302. /******************************Public*Routine******************************\
  303. * vInitPolyArrayBuffer
  304. *
  305. * Initialize the POLYARRAY/POLYDATA buffer pointed to by pdBuf.
  306. *
  307. * History:
  308. * 12-Feb-1996 -by- Gilman Wong [gilmanw]
  309. * Wrote it.
  310. \**************************************************************************/
  311. VOID FASTCALL vInitPolyArrayBuffer(__GLcontext *gc, POLYDATA *pdBuf,
  312. UINT pdBufSizeBytes, UINT pdBufSize)
  313. {
  314. UINT i;
  315. POLYDATA *pdBufSAVE;
  316. GLuint pdBufSizeBytesSAVE;
  317. GLuint pdBufSizeSAVE;
  318. //
  319. // Save current polyarray buffer. We are going to temporarily
  320. // replace the current one with the new one for the purposes
  321. // of initializing the buffer. However, it is too early to
  322. // replace the current polyarray. The higher level code will
  323. // figure that out later.
  324. //
  325. pdBufSAVE = gc->vertex.pdBuf;
  326. pdBufSizeBytesSAVE = gc->vertex.pdBufSizeBytes;
  327. pdBufSizeSAVE = gc->vertex.pdBufSize;
  328. //
  329. // Set polyarray buffer to memory allocated by MCD.
  330. //
  331. gc->vertex.pdBuf = pdBuf;
  332. gc->vertex.pdBufSizeBytes = pdBufSizeBytes;
  333. gc->vertex.pdBufSize = pdBufSize;
  334. //
  335. // Initialize the vertex buffer.
  336. //
  337. PolyArrayResetBuffer(gc);
  338. //
  339. // Restore the polyarray buffer.
  340. //
  341. gc->vertex.pdBuf = pdBufSAVE;
  342. gc->vertex.pdBufSizeBytes = pdBufSizeBytesSAVE;
  343. gc->vertex.pdBufSize = pdBufSizeSAVE;
  344. }
  345. /******************************Public*Routine******************************\
  346. * GenMcdSetScaling
  347. *
  348. * Set up the various scale values needed for MCD or generic operation.
  349. *
  350. * This should be called when toggling between accelerated/non-accelerated
  351. * operation.
  352. *
  353. * Returns:
  354. * None.
  355. *
  356. * History:
  357. * 03-May-1996 -by- Otto Berkes [ottob]
  358. * Wrote it.
  359. \**************************************************************************/
  360. VOID FASTCALL GenMcdSetScaling(__GLGENcontext *gengc)
  361. {
  362. __GLcontext *gc = (__GLcontext *)gengc;
  363. GENMCDSTATE *pMcdState = gengc->pMcdState;
  364. __GLviewport *vp = &gc->state.viewport;
  365. double scale;
  366. //
  367. // If we're using MCD, set up the desired scale value:
  368. //
  369. if (pMcdState) {
  370. if (pMcdState->McdRcInfo.requestFlags & MCDRCINFO_DEVZSCALE)
  371. gengc->genAccel.zDevScale = pMcdState->McdRcInfo.zScale;
  372. else
  373. gengc->genAccel.zDevScale = pMcdState->McdRcInfo.depthBufferMax;
  374. } else if (gengc->_pMcdState)
  375. gengc->genAccel.zDevScale = gengc->_pMcdState->McdRcInfo.depthBufferMax;
  376. if (pMcdState)
  377. scale = gengc->genAccel.zDevScale * __glHalf;
  378. else
  379. scale = gc->depthBuffer.scale * __glHalf;
  380. gc->state.viewport.zScale = (__GLfloat)((vp->zFar - vp->zNear) * scale);
  381. gc->state.viewport.zCenter = (__GLfloat)((vp->zFar + vp->zNear) * scale);
  382. if (pMcdState && pMcdState->McdRcInfo.requestFlags & MCDRCINFO_NOVIEWPORTADJUST) {
  383. gc->constants.viewportXAdjust = 0;
  384. gc->constants.viewportYAdjust = 0;
  385. gc->constants.fviewportXAdjust = (__GLfloat)0.0;
  386. gc->constants.fviewportYAdjust = (__GLfloat)0.0;
  387. } else {
  388. gc->constants.viewportXAdjust = __GL_VERTEX_X_BIAS + __GL_VERTEX_X_FIX;
  389. gc->constants.viewportYAdjust = __GL_VERTEX_Y_BIAS + __GL_VERTEX_Y_FIX;
  390. gc->constants.fviewportXAdjust = (__GLfloat)gc->constants.viewportXAdjust;
  391. gc->constants.fviewportYAdjust = (__GLfloat)gc->constants.viewportYAdjust;
  392. }
  393. //
  394. // The inverses for these are set in __glContextSetColorScales which is
  395. // called on each MakeCurrent:
  396. //
  397. if (pMcdState && pMcdState->McdRcInfo.requestFlags & MCDRCINFO_DEVCOLORSCALE) {
  398. gc->redVertexScale = pMcdState->McdRcInfo.redScale;
  399. gc->greenVertexScale = pMcdState->McdRcInfo.greenScale;
  400. gc->blueVertexScale = pMcdState->McdRcInfo.blueScale;
  401. gc->alphaVertexScale = pMcdState->McdRcInfo.alphaScale;
  402. } else {
  403. if (gc->modes.colorIndexMode) {
  404. gc->redVertexScale = (MCDFLOAT)1.0;
  405. gc->greenVertexScale = (MCDFLOAT)1.0;
  406. gc->blueVertexScale = (MCDFLOAT)1.0;
  407. gc->alphaVertexScale = (MCDFLOAT)1.0;
  408. } else {
  409. gc->redVertexScale = (MCDFLOAT)((1 << gc->modes.redBits) - 1);
  410. gc->greenVertexScale = (MCDFLOAT)((1 << gc->modes.greenBits) - 1);
  411. gc->blueVertexScale = (MCDFLOAT)((1 << gc->modes.blueBits) - 1);
  412. if( gc->modes.alphaBits )
  413. gc->alphaVertexScale = (MCDFLOAT)((1 << gc->modes.alphaBits) - 1);
  414. else
  415. gc->alphaVertexScale = (MCDFLOAT)((1 << gc->modes.redBits) - 1);
  416. }
  417. }
  418. gc->redClampTable[1] = gc->redVertexScale;
  419. gc->redClampTable[2] = (__GLfloat)0.0;
  420. gc->redClampTable[3] = (__GLfloat)0.0;
  421. gc->greenClampTable[1] = gc->greenVertexScale;
  422. gc->greenClampTable[2] = (__GLfloat)0.0;
  423. gc->greenClampTable[3] = (__GLfloat)0.0;
  424. gc->blueClampTable[1] = gc->blueVertexScale;
  425. gc->blueClampTable[2] = (__GLfloat)0.0;
  426. gc->blueClampTable[3] = (__GLfloat)0.0;
  427. gc->alphaClampTable[1] = gc->alphaVertexScale;
  428. gc->alphaClampTable[2] = (__GLfloat)0.0;
  429. gc->alphaClampTable[3] = (__GLfloat)0.0;
  430. if (pMcdState && pMcdState->McdRcInfo.requestFlags & MCDRCINFO_Y_LOWER_LEFT) {
  431. gc->constants.yInverted = GL_FALSE;
  432. gc->constants.ySign = 1;
  433. } else {
  434. gc->constants.yInverted = GL_TRUE;
  435. gc->constants.ySign = -1;
  436. }
  437. }
  438. /******************************Public*Routine******************************\
  439. *
  440. * McdPixelFormatFromPfd
  441. *
  442. * Fills out an MCDPIXELFORMAT from a PIXELFORMATDESCRIPTOR
  443. *
  444. * History:
  445. * Mon Sep 16 14:51:42 1996 -by- Drew Bliss [drewb]
  446. * Created
  447. *
  448. \**************************************************************************/
  449. VOID FASTCALL McdPixelFormatFromPfd(PIXELFORMATDESCRIPTOR *pfd,
  450. MCDPIXELFORMAT *mpf)
  451. {
  452. mpf->nSize = sizeof(MCDPIXELFORMAT);
  453. mpf->dwFlags = pfd->dwFlags & (PFD_DOUBLEBUFFER |
  454. PFD_NEED_PALETTE |
  455. PFD_NEED_SYSTEM_PALETTE |
  456. PFD_SWAP_EXCHANGE |
  457. PFD_SWAP_COPY |
  458. PFD_SWAP_LAYER_BUFFERS);
  459. mpf->iPixelType = pfd->iPixelType;
  460. mpf->cColorBits = pfd->cColorBits;
  461. mpf->cRedBits = pfd->cRedBits;
  462. mpf->cRedShift = pfd->cRedShift;
  463. mpf->cGreenBits = pfd->cGreenBits;
  464. mpf->cGreenShift = pfd->cGreenShift;
  465. mpf->cBlueBits = pfd->cBlueBits;
  466. mpf->cBlueShift = pfd->cBlueShift;
  467. mpf->cAlphaBits = pfd->cAlphaBits;
  468. mpf->cAlphaShift = pfd->cAlphaShift;
  469. mpf->cDepthBits = pfd->cDepthBits;
  470. mpf->cDepthShift = 0;
  471. mpf->cDepthBufferBits = pfd->cDepthBits;
  472. mpf->cStencilBits = pfd->cStencilBits;
  473. mpf->cOverlayPlanes = pfd->bReserved & 0xf;
  474. mpf->cUnderlayPlanes = pfd->bReserved >> 4;
  475. mpf->dwTransparentColor = pfd->dwVisibleMask;
  476. }
  477. /******************************Public*Routine******************************\
  478. * GenMcdResetViewportAdj
  479. *
  480. * If an MCD driver that specifies MCDRCINFO_NOVIEWPORTADJUST kicks back
  481. * for simulations, we need to change the viewport adjust values from
  482. * 0, 0 back to the default values in order to run the software
  483. * implementation.
  484. *
  485. * If biasType is VP_FIXBIAS, this function will set the viewport adjust
  486. * values to their software default.
  487. *
  488. * If biasType is VP_NOBIAS, this function will set the viewport adjust
  489. * values to zero.
  490. *
  491. * Returns:
  492. * TRUE is viewport is set, FALSE otherwise.
  493. *
  494. * Note:
  495. * The main reason for returning a BOOL is so that caller can check if
  496. * VP_FIXBIAS succeeds. If it does, it needs to reset values back to
  497. * VP_NOBIAS.
  498. *
  499. * Also note that it is safe for non-MCD and MCD that does not set
  500. * MCDRCINFO_NOVIEWPORTADJUST to call this function. This function
  501. * will do nothing in these situations and will return FALSE.
  502. *
  503. * History:
  504. * 22-May-1997 -by- Gilman Wong [gilmanw]
  505. * Wrote it.
  506. \**************************************************************************/
  507. BOOL FASTCALL GenMcdResetViewportAdj(__GLcontext *gc, VP_BIAS_TYPE biasType)
  508. {
  509. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  510. BOOL bRet = FALSE;
  511. if (gengc->pMcdState &&
  512. (gengc->pMcdState->McdRcInfo.requestFlags & MCDRCINFO_NOVIEWPORTADJUST))
  513. {
  514. switch (biasType)
  515. {
  516. case VP_FIXBIAS:
  517. if (gc->constants.viewportXAdjust == 0)
  518. {
  519. //
  520. // The state of viewportYAdjust should match
  521. // viewportXAdjust. If not, the test should be
  522. // changed (perhaps state flag in the context to
  523. // track biasing).
  524. //
  525. ASSERTOPENGL((gc->constants.viewportYAdjust == 0),
  526. "GenMcdResetViewportAdj: "
  527. "viewportYAdjust not zero\n");
  528. gc->constants.viewportXAdjust = __GL_VERTEX_X_BIAS +
  529. __GL_VERTEX_X_FIX;
  530. gc->constants.viewportYAdjust = __GL_VERTEX_Y_BIAS +
  531. __GL_VERTEX_Y_FIX;
  532. gc->constants.fviewportXAdjust = (__GLfloat)gc->constants.viewportXAdjust;
  533. gc->constants.fviewportYAdjust = (__GLfloat)gc->constants.viewportYAdjust;
  534. //
  535. // Apply new bias to the rasterPos.
  536. //
  537. gc->state.current.rasterPos.window.x += gc->constants.fviewportXAdjust;
  538. gc->state.current.rasterPos.window.y += gc->constants.fviewportYAdjust;
  539. }
  540. bRet = TRUE;
  541. break;
  542. case VP_NOBIAS:
  543. if (gc->constants.viewportXAdjust != 0)
  544. {
  545. //
  546. // The state of viewportYAdjust should match
  547. // viewportXAdjust. If not, the test should be
  548. // changed (perhaps state flag in the context to
  549. // track biasing).
  550. //
  551. ASSERTOPENGL((gc->constants.viewportYAdjust != 0),
  552. "GenMcdResetViewportAdj: "
  553. "viewportYAdjust zero\n");
  554. //
  555. // Remove bias from the rasterPos before resetting.
  556. //
  557. gc->state.current.rasterPos.window.x -= gc->constants.fviewportXAdjust;
  558. gc->state.current.rasterPos.window.y -= gc->constants.fviewportYAdjust;
  559. gc->constants.viewportXAdjust = 0;
  560. gc->constants.viewportYAdjust = 0;
  561. gc->constants.fviewportXAdjust = (__GLfloat)0.0;
  562. gc->constants.fviewportYAdjust = (__GLfloat)0.0;
  563. }
  564. bRet = TRUE;
  565. break;
  566. default:
  567. DBGPRINT("GenMcdResetViewportAdj: unknown type\n");
  568. break;
  569. }
  570. if (bRet)
  571. {
  572. __GLbeginMode beginMode = gc->beginMode;
  573. //
  574. // Why save/restore beginMode?
  575. //
  576. // Because we are playing around with the viewport values,
  577. // ApplyViewport may inadvertently set beginMode to
  578. // __GL_NEED_VALIDATE even though we will later restore the
  579. // original viewport values. This can confuse glim_DrawPolyArray
  580. // which plays around with the beginMode settings.
  581. //
  582. __glUpdateViewport(gc);
  583. (gc->procs.applyViewport)(gc);
  584. __glUpdateViewportDependents(gc);
  585. gc->beginMode = beginMode;
  586. }
  587. }
  588. return bRet;
  589. }
  590. /******************************Public*Routine******************************\
  591. * bInitMcdContext
  592. *
  593. * Allocate and initialize the GENMCDSTATE structure. Create MCD context
  594. * and shared memory buffers used to pass vertex arrays, commands, and state.
  595. *
  596. * This state exists per-context.
  597. *
  598. * Returns:
  599. * TRUE if successful, FALSE otherwise.
  600. * In addition, the gengc->pMcdState is valid IFF successful.
  601. *
  602. * History:
  603. * 05-Feb-1996 -by- Gilman Wong [gilmanw]
  604. * Wrote it.
  605. \**************************************************************************/
  606. BOOL FASTCALL bInitMcdContext(__GLGENcontext *gengc, GLGENwindow *pwnd)
  607. {
  608. BOOL bRet = FALSE;
  609. __GLcontext *gc = &gengc->gc;
  610. GENMCDSTATE *pMcdState = (GENMCDSTATE *) NULL;
  611. ULONG ulBytes;
  612. UINT nVertices;
  613. UINT pdBufSize;
  614. POLYDATA *pd;
  615. DWORD dwFlags;
  616. MCDRCINFOPRIV mriPriv;
  617. //
  618. // This functions cannot assume MCD entry point table is already
  619. // initialized.
  620. //
  621. if (!bInitMcd(gengc->gsurf.hdc))
  622. {
  623. goto bInitMcdContext_exit;
  624. }
  625. //
  626. // Fail if not an MCD pixelformat.
  627. //
  628. if (!(gengc->gsurf.pfd.dwFlags & PFD_GENERIC_ACCELERATED))
  629. {
  630. goto bInitMcdContext_exit;
  631. }
  632. //
  633. // Allocate memory for our MCD state.
  634. //
  635. pMcdState = (GENMCDSTATE *)ALLOCZ(sizeof(*gengc->pMcdState));
  636. if (pMcdState)
  637. {
  638. //
  639. // Create an MCD context.
  640. //
  641. //
  642. // Pickup viewportXAdjust and viewportYAdjust from the constants section
  643. // of the gc.
  644. //
  645. pMcdState->McdRcInfo.viewportXAdjust = gengc->gc.constants.viewportXAdjust;
  646. pMcdState->McdRcInfo.viewportYAdjust = gengc->gc.constants.viewportYAdjust;
  647. if (!gengc->gsurf.pfd.cDepthBits || (gengc->gsurf.pfd.cDepthBits >= 32))
  648. pMcdState->McdRcInfo.depthBufferMax = ~((ULONG)0);
  649. else
  650. pMcdState->McdRcInfo.depthBufferMax = (1 << gengc->gsurf.pfd.cDepthBits) - 1;
  651. //!!!
  652. //!!! This is broken since we can't use the full z-buffer range!
  653. //!!!
  654. pMcdState->McdRcInfo.depthBufferMax >>= 1;
  655. pMcdState->McdRcInfo.zScale = (MCDDOUBLE)pMcdState->McdRcInfo.depthBufferMax;
  656. //
  657. // This is also computed by initCi/initRGB, but this function
  658. // is called before the color buffers are initialized:
  659. //
  660. if (gc->modes.colorIndexMode)
  661. {
  662. pMcdState->McdRcInfo.redScale = (MCDFLOAT)1.0;
  663. pMcdState->McdRcInfo.greenScale = (MCDFLOAT)1.0;
  664. pMcdState->McdRcInfo.blueScale = (MCDFLOAT)1.0;
  665. pMcdState->McdRcInfo.alphaScale = (MCDFLOAT)1.0;
  666. }
  667. else
  668. {
  669. pMcdState->McdRcInfo.redScale = (MCDFLOAT)((1 << gc->modes.redBits) - 1);
  670. pMcdState->McdRcInfo.greenScale = (MCDFLOAT)((1 << gc->modes.greenBits) - 1);
  671. pMcdState->McdRcInfo.blueScale = (MCDFLOAT)((1 << gc->modes.blueBits) - 1);
  672. pMcdState->McdRcInfo.alphaScale = (MCDFLOAT)((1 << gc->modes.redBits) - 1);
  673. }
  674. dwFlags = 0;
  675. // Consider - Extract clipper-associated hwnds? Whole clipping
  676. // scheme is broken until clipper data can be accessed in kernel.
  677. if ((gengc->gsurf.dwFlags & GLSURF_DIRECTDRAW) == 0)
  678. {
  679. dwFlags |= MCDSURFACE_HWND;
  680. }
  681. else
  682. {
  683. // Cache kernel-mode surface handles for DirectDraw
  684. // This must occur before the call to MCDCreateContext
  685. pMcdState->hDdColor = (HANDLE)
  686. ((LPDDRAWI_DDRAWSURFACE_INT)gengc->gsurf.dd.gddsFront.pdds)->
  687. lpLcl->hDDSurface;
  688. if (gengc->gsurf.dd.gddsZ.pdds != NULL)
  689. {
  690. pMcdState->hDdDepth = (HANDLE)
  691. ((LPDDRAWI_DDRAWSURFACE_INT)gengc->gsurf.dd.gddsZ.pdds)->
  692. lpLcl->hDDSurface;
  693. }
  694. }
  695. if (SUPPORTS_DIRECT())
  696. {
  697. dwFlags |= MCDSURFACE_DIRECT;
  698. }
  699. mriPriv.mri = pMcdState->McdRcInfo;
  700. if (!(gpMcdTable->pMCDCreateContext)(&pMcdState->McdContext,
  701. &mriPriv,
  702. &gengc->gsurf,
  703. pwnd->ipfd - pwnd->ipfdDevMax,
  704. dwFlags))
  705. {
  706. WARNING("bInitMcdContext: MCDCreateContext failed\n");
  707. goto bInitMcdContext_exit;
  708. }
  709. pMcdState->McdRcInfo = mriPriv.mri;
  710. //
  711. // Get MCDPIXELFORMAT and cache in GENMCDSTATE.
  712. //
  713. if (gengc->gsurf.dwFlags & GLSURF_DIRECTDRAW)
  714. {
  715. McdPixelFormatFromPfd(&gengc->gsurf.pfd, &pMcdState->McdPixelFmt);
  716. }
  717. else if (!(gpMcdTable->pMCDDescribeMcdPixelFormat)
  718. (gengc->gsurf.hdc,
  719. pwnd->ipfd - pwnd->ipfdDevMax,
  720. &pMcdState->McdPixelFmt))
  721. {
  722. WARNING("bInitMcdContext: MCDDescribeMcdPixelFormat failed\n");
  723. goto bInitMcdContext_exit;
  724. }
  725. //
  726. // Allocate cmd/state buffer.
  727. //
  728. //!!!mcd -- How much memory should be allocated for cmd buffer?
  729. //!!!mcd Use a page (4K) for now...
  730. ulBytes = 4096;
  731. pMcdState->McdCmdBatch.size = ulBytes;
  732. pMcdState->McdCmdBatch.pv =
  733. (gpMcdTable->pMCDAlloc)(&pMcdState->McdContext, ulBytes,
  734. &pMcdState->McdCmdBatch.hmem, 0);
  735. if (!pMcdState->McdCmdBatch.pv)
  736. {
  737. WARNING("bInitMcdContext: state buf MCDAlloc failed\n");
  738. goto bInitMcdContext_exit;
  739. }
  740. //
  741. // Determine size of vertex buffer we should use with MCD driver.
  742. // This is calculated by taking the size the MCD driver requests
  743. // and computing the number of POLYDATA structure that will fit.
  744. // If the result is less than the minimum size required by the
  745. // generic software implementation, bump it up to the minimum.
  746. //
  747. ulBytes = McdDriverInfo.mcdDriverInfo.drvBatchMemSizeMax;
  748. nVertices = ulBytes / sizeof(POLYDATA);
  749. if (nVertices < MINIMUM_POLYDATA_BUFFER_SIZE)
  750. {
  751. ulBytes = MINIMUM_POLYDATA_BUFFER_SIZE * sizeof(POLYDATA);
  752. nVertices = MINIMUM_POLYDATA_BUFFER_SIZE;
  753. }
  754. //
  755. // Only n-1 vertices are used for the buffer. The "extra" is
  756. // reserved for use by the polyarray code (see PolyArrayAllocBuf
  757. // in so_prim.c).
  758. //
  759. pdBufSize = nVertices - 1;
  760. //
  761. // Allocate vertex buffers.
  762. //
  763. if (McdDriverInfo.mcdDriverInfo.drvMemFlags & MCDRV_MEM_DMA)
  764. {
  765. pMcdState->McdBuf2.size = ulBytes;
  766. pMcdState->McdBuf2.pv =
  767. (gpMcdTable->pMCDAlloc)(&pMcdState->McdContext, ulBytes,
  768. &pMcdState->McdBuf2.hmem, 0);
  769. if (pMcdState->McdBuf2.pv)
  770. {
  771. //
  772. // Configure memory buffer as a POLYDATA buffer.
  773. //
  774. vInitPolyArrayBuffer(gc, (POLYDATA *) pMcdState->McdBuf2.pv,
  775. ulBytes, pdBufSize);
  776. }
  777. else
  778. {
  779. WARNING("bInitMcdContext: 2nd MCDAlloc failed\n");
  780. goto bInitMcdContext_exit;
  781. }
  782. }
  783. pMcdState->McdBuf1.size = ulBytes;
  784. pMcdState->McdBuf1.pv =
  785. (gpMcdTable->pMCDAlloc)(&pMcdState->McdContext, ulBytes,
  786. &pMcdState->McdBuf1.hmem, 0);
  787. if (pMcdState->McdBuf1.pv)
  788. {
  789. pMcdState->pMcdPrimBatch = &pMcdState->McdBuf1;
  790. //
  791. // Configure memory buffer as a POLYDATA buffer.
  792. //
  793. vInitPolyArrayBuffer(gc, (POLYDATA *) pMcdState->McdBuf1.pv,
  794. ulBytes, pdBufSize);
  795. //
  796. // Free current poly array buffer.
  797. //
  798. // If we fail after this, we must call PolyArrayAllocBuffer to
  799. // restore the poly array buffer. Luckily, at this point we
  800. // are guaranteed not fail.
  801. //
  802. PolyArrayFreeBuffer(gc);
  803. //
  804. // Set poly array buffer to memory allocated by MCD.
  805. //
  806. gc->vertex.pdBuf = (POLYDATA *) pMcdState->pMcdPrimBatch->pv;
  807. gc->vertex.pdBufSizeBytes = ulBytes;
  808. gc->vertex.pdBufSize = pdBufSize;
  809. }
  810. else
  811. {
  812. WARNING("bInitMcdContext: MCDAlloc failed\n");
  813. goto bInitMcdContext_exit;
  814. }
  815. if (pwnd->dwMcdWindow == 0)
  816. {
  817. //
  818. // Save MCD server-side window handle in the GENwindow
  819. //
  820. pwnd->dwMcdWindow = mriPriv.dwMcdWindow;
  821. }
  822. else
  823. {
  824. ASSERTOPENGL(pwnd->dwMcdWindow == mriPriv.dwMcdWindow,
  825. "dwMcdWindow mismatch\n");
  826. }
  827. //
  828. // Finally, success.
  829. //
  830. bRet = TRUE;
  831. }
  832. bInitMcdContext_exit:
  833. //
  834. // If function failed, cleanup allocated resources.
  835. //
  836. if (!bRet)
  837. {
  838. if (pMcdState)
  839. {
  840. if (pMcdState->McdBuf1.pv)
  841. {
  842. (gpMcdTable->pMCDFree)(&pMcdState->McdContext, pMcdState->McdBuf1.pv);
  843. }
  844. if (pMcdState->McdBuf2.pv)
  845. {
  846. (gpMcdTable->pMCDFree)(&pMcdState->McdContext, pMcdState->McdBuf2.pv);
  847. }
  848. if (pMcdState->McdCmdBatch.pv)
  849. {
  850. (gpMcdTable->pMCDFree)(&pMcdState->McdContext, pMcdState->McdCmdBatch.pv);
  851. }
  852. if (pMcdState->McdContext.hMCDContext)
  853. {
  854. (gpMcdTable->pMCDDeleteContext)(&pMcdState->McdContext);
  855. }
  856. FREE(pMcdState);
  857. }
  858. gengc->_pMcdState = (GENMCDSTATE *) NULL;
  859. }
  860. else
  861. {
  862. gengc->_pMcdState = pMcdState;
  863. //
  864. // For generic formats, the depth resolution (i.e., number of
  865. // active depth bits) and the depth "pixel stride" are the same.
  866. // So GetContextModes, which sets modes.depthBits, can use the
  867. // PIXELFORMATDESCRIPTOR.cDepthBits for generic pixel formats.
  868. //
  869. // However, these two quantities can differ for MCD, so we need
  870. // to set it to cDepthBufferBits once we know that this is an
  871. // MCD context.
  872. //
  873. if (gengc->_pMcdState)
  874. gengc->gc.modes.depthBits = gengc->_pMcdState->McdPixelFmt.cDepthBufferBits;
  875. }
  876. gengc->pMcdState = (GENMCDSTATE *) NULL;
  877. return bRet;
  878. }
  879. /******************************Public*Routine******************************\
  880. * bInitMcdSurface
  881. *
  882. * Allocate and initialize the GENMCDSURFACE structure. This includes
  883. * creating shared span buffers to read/write the MCD front, back and depth
  884. * buffers.
  885. *
  886. * The MCDBUFFERS structure, which describes the location of the MCD buffers
  887. * (if directly accessible), is left zero-initialized. The contents of this
  888. * structure are only valid when the screen lock is held and must be reset each
  889. * time direct screen access is started.
  890. *
  891. * This function, if successful, will also bind the MCD context to the MCD
  892. * surface.
  893. *
  894. * This state exists per-window.
  895. *
  896. * Returns:
  897. * TRUE if successful, FALSE otherwise.
  898. * In addition, the gengc->pMcdState is valid IFF successful.
  899. *
  900. * History:
  901. * 05-Feb-1996 -by- Gilman Wong [gilmanw]
  902. * Wrote it.
  903. \**************************************************************************/
  904. BOOL FASTCALL bInitMcdSurface(__GLGENcontext *gengc, GLGENwindow *pwnd,
  905. __GLGENbuffers *buffers)
  906. {
  907. BOOL bRet = FALSE;
  908. __GLcontext *gc = &gengc->gc;
  909. GENMCDSTATE *pMcdState;
  910. GENMCDSURFACE *pMcdSurf = (GENMCDSURFACE *) NULL;
  911. ULONG ulBytes;
  912. UINT nVertices;
  913. POLYDATA *pd;
  914. //
  915. // This function can assume that MCD entry point table is already
  916. // initialized as we cannot get here without MCD already having been
  917. // called.
  918. //
  919. ASSERTOPENGL(gpMcdTable, "bInitMcdSurface: mcd32.dll not initialized\n");
  920. //
  921. // Fail if no MCD context.
  922. //
  923. if (!(pMcdState = gengc->_pMcdState))
  924. {
  925. goto bInitMcdSurface_exit;
  926. }
  927. //
  928. // Allocate memory for our MCD surface.
  929. //
  930. pMcdSurf = (GENMCDSURFACE *)ALLOCZ(sizeof(*buffers->pMcdSurf));
  931. if (pMcdSurf)
  932. {
  933. //
  934. // Remember the window this surface is bound to.
  935. //
  936. pMcdSurf->pwnd = pwnd;
  937. //
  938. // Allocate scanline depth buffer. Used to read/write depth buffer
  939. // spans.
  940. //
  941. if (pMcdState->McdPixelFmt.cDepthBits)
  942. {
  943. pMcdSurf->McdDepthBuf.size =
  944. MCD_MAX_SCANLINE * ((pMcdState->McdPixelFmt.cDepthBufferBits + 7) >> 3);
  945. pMcdSurf->McdDepthBuf.pv =
  946. (gpMcdTable->pMCDAlloc)(&pMcdState->McdContext,
  947. pMcdSurf->McdDepthBuf.size,
  948. &pMcdSurf->McdDepthBuf.hmem, 0);
  949. if (!pMcdSurf->McdDepthBuf.pv)
  950. {
  951. WARNING("bInitMcdSurface: MCDAlloc depth buf failed\n");
  952. goto bInitMcdSurface_exit;
  953. }
  954. //
  955. // A 32-bit depth span is required by generic implementation for
  956. // simulations. If cDepthBufferBits < 32, then we need to allocate
  957. // a separate buffer to do the conversion.
  958. //
  959. if (pMcdState->McdPixelFmt.cDepthBufferBits < 32)
  960. {
  961. pMcdSurf->pDepthSpan =
  962. (__GLzValue *)ALLOC(sizeof(__GLzValue) * MCD_MAX_SCANLINE);
  963. if (!pMcdSurf->pDepthSpan)
  964. {
  965. WARNING("bInitMcdSurface: malloc depth buf failed\n");
  966. goto bInitMcdSurface_exit;
  967. }
  968. }
  969. else
  970. {
  971. pMcdSurf->pDepthSpan = (__GLzValue *) pMcdSurf->McdDepthBuf.pv;
  972. }
  973. }
  974. else
  975. {
  976. pMcdSurf->McdDepthBuf.pv = (PVOID) NULL;
  977. pMcdSurf->pDepthSpan = (PVOID) NULL;
  978. }
  979. pMcdSurf->depthBitMask = (~0) << (32 - pMcdState->McdPixelFmt.cDepthBits);
  980. //
  981. // Allocate scanline color buffer. Used to read/write front/back
  982. // buffer spans.
  983. //
  984. pMcdSurf->McdColorBuf.size =
  985. MCD_MAX_SCANLINE * ((pMcdState->McdPixelFmt.cColorBits + 7) >> 3);
  986. pMcdSurf->McdColorBuf.pv =
  987. (gpMcdTable->pMCDAlloc)(&pMcdState->McdContext,
  988. pMcdSurf->McdColorBuf.size,
  989. &pMcdSurf->McdColorBuf.hmem, 0);
  990. if (!pMcdSurf->McdColorBuf.pv)
  991. {
  992. WARNING("bInitMcdSurface: MCDAlloc color buf failed\n");
  993. goto bInitMcdSurface_exit;
  994. }
  995. //
  996. // Finally, success.
  997. //
  998. bRet = TRUE;
  999. }
  1000. bInitMcdSurface_exit:
  1001. //
  1002. // If function failed, cleanup allocated resources.
  1003. //
  1004. if (!bRet)
  1005. {
  1006. if (pMcdSurf)
  1007. {
  1008. if (pMcdSurf->McdColorBuf.pv)
  1009. {
  1010. (gpMcdTable->pMCDFree)(&pMcdState->McdContext, pMcdSurf->McdColorBuf.pv);
  1011. }
  1012. if (pMcdSurf->pDepthSpan != pMcdSurf->McdDepthBuf.pv)
  1013. {
  1014. FREE(pMcdSurf->pDepthSpan);
  1015. }
  1016. if (pMcdSurf->McdDepthBuf.pv)
  1017. {
  1018. (gpMcdTable->pMCDFree)(&pMcdState->McdContext, pMcdSurf->McdDepthBuf.pv);
  1019. }
  1020. FREE(pMcdSurf);
  1021. buffers->pMcdSurf = (GENMCDSURFACE *) NULL;
  1022. pMcdState->pMcdSurf = (GENMCDSURFACE *) NULL;
  1023. }
  1024. }
  1025. else
  1026. {
  1027. //
  1028. // Surface created. Save it in the __GLGENbuffers.
  1029. //
  1030. buffers->pMcdSurf = pMcdSurf;
  1031. //
  1032. // Bind the context to the surface.
  1033. // Sounds fancy, but it really just means save a copy of pointer
  1034. // (and a copy of the pDepthSpan for convenience).
  1035. //
  1036. pMcdState->pMcdSurf = pMcdSurf;
  1037. pMcdState->pDepthSpan = pMcdSurf->pDepthSpan;
  1038. //
  1039. // MCD state is now fully created and bound to a surface.
  1040. // OK to connect pMcdState to the _pMcdState.
  1041. //
  1042. gengc->pMcdState = gengc->_pMcdState;
  1043. gengc->pMcdState->mcdFlags |= (MCD_STATE_FORCEPICK | MCD_STATE_FORCERESIZE);
  1044. }
  1045. return bRet;
  1046. }
  1047. /******************************Public*Routine******************************\
  1048. * GenMcdDeleteContext
  1049. *
  1050. * Delete the resources belonging to the MCD context (including the context).
  1051. *
  1052. * History:
  1053. * 16-Feb-1996 -by- Gilman Wong [gilmanw]
  1054. * Wrote it.
  1055. \**************************************************************************/
  1056. void FASTCALL GenMcdDeleteContext(GENMCDSTATE *pMcdState)
  1057. {
  1058. //
  1059. // This function can assume that MCD entry point table is already
  1060. // initialized as we cannot get here without MCD already having been
  1061. // called.
  1062. //
  1063. ASSERTOPENGL(gpMcdTable, "GenMcdDeleteContext: mcd32.dll not initialized\n");
  1064. if (pMcdState)
  1065. {
  1066. if (pMcdState->McdBuf1.pv)
  1067. {
  1068. (gpMcdTable->pMCDFree)(&pMcdState->McdContext, pMcdState->McdBuf1.pv);
  1069. }
  1070. if (pMcdState->McdBuf2.pv)
  1071. {
  1072. (gpMcdTable->pMCDFree)(&pMcdState->McdContext, pMcdState->McdBuf2.pv);
  1073. }
  1074. if (pMcdState->McdCmdBatch.pv)
  1075. {
  1076. (gpMcdTable->pMCDFree)(&pMcdState->McdContext, pMcdState->McdCmdBatch.pv);
  1077. }
  1078. if (pMcdState->McdContext.hMCDContext)
  1079. {
  1080. (gpMcdTable->pMCDDeleteContext)(&pMcdState->McdContext);
  1081. }
  1082. FREE(pMcdState);
  1083. }
  1084. }
  1085. /******************************Public*Routine******************************\
  1086. * GenMcdDeleteSurface
  1087. *
  1088. * Delete the resources belonging to the MCD surface.
  1089. *
  1090. * History:
  1091. * 16-Feb-1996 -by- Gilman Wong [gilmanw]
  1092. * Wrote it.
  1093. \**************************************************************************/
  1094. void FASTCALL GenMcdDeleteSurface(GENMCDSURFACE *pMcdSurf)
  1095. {
  1096. //
  1097. // This function can assume that MCD entry point table is already
  1098. // initialized as we cannot get here without MCD already having been
  1099. // called.
  1100. //
  1101. ASSERTOPENGL(gpMcdTable, "GenMcdDeleteSurface: mcd32.dll not initialized\n");
  1102. if (pMcdSurf)
  1103. {
  1104. MCDCONTEXT McdContext;
  1105. //
  1106. // If a separate depth interchange buffer was allocated, delete it.
  1107. //
  1108. if (pMcdSurf->pDepthSpan != pMcdSurf->McdDepthBuf.pv)
  1109. {
  1110. FREE(pMcdSurf->pDepthSpan);
  1111. }
  1112. //
  1113. // A valid McdContext is not guaranteed to exist at the time this function
  1114. // is called. Therefore, need to fake up an McdContext with which to call
  1115. // MCDFree. Currently, the only thing in the McdContext that needs to be
  1116. // valid in order to call MCDFree is the hdc field.
  1117. //
  1118. memset(&McdContext, 0, sizeof(McdContext));
  1119. if (pMcdSurf->pwnd->gwid.iType == GLWID_DDRAW)
  1120. {
  1121. McdContext.hdc = pMcdSurf->pwnd->gwid.hdc;
  1122. }
  1123. else
  1124. {
  1125. McdContext.hdc = GetDC(pMcdSurf->pwnd->gwid.hwnd);
  1126. }
  1127. if (McdContext.hdc)
  1128. {
  1129. if (pMcdSurf->McdColorBuf.pv)
  1130. {
  1131. (gpMcdTable->pMCDFree)(&McdContext, pMcdSurf->McdColorBuf.pv);
  1132. }
  1133. if (pMcdSurf->McdDepthBuf.pv)
  1134. {
  1135. (gpMcdTable->pMCDFree)(&McdContext, pMcdSurf->McdDepthBuf.pv);
  1136. }
  1137. if (pMcdSurf->pwnd->gwid.iType != GLWID_DDRAW)
  1138. {
  1139. ReleaseDC(pMcdSurf->pwnd->gwid.hwnd, McdContext.hdc);
  1140. }
  1141. }
  1142. //
  1143. // Delete the GENMCDSURFACE structure.
  1144. //
  1145. FREE(pMcdSurf);
  1146. }
  1147. }
  1148. /******************************Public*Routine******************************\
  1149. * GenMcdMakeCurrent
  1150. *
  1151. * Call MCD driver to bind specified context to window.
  1152. *
  1153. * Returns:
  1154. * TRUE if successful, FALSE otherwise.
  1155. *
  1156. * History:
  1157. * 03-Apr-1996 -by- Gilman Wong [gilmanw]
  1158. * Wrote it.
  1159. \**************************************************************************/
  1160. BOOL FASTCALL GenMcdMakeCurrent(__GLGENcontext *gengc, GLGENwindow *pwnd)
  1161. {
  1162. BOOL bRet;
  1163. GENMCDSTATE *pMcdState = gengc->pMcdState;
  1164. ASSERTOPENGL(gengc->pMcdState, "GenMcdMakeCurrent: null pMcdState\n");
  1165. //
  1166. // This function can assume that MCD entry point table is already
  1167. // initialized as we cannot get here without MCD already having been
  1168. // called.
  1169. //
  1170. ASSERTOPENGL(gpMcdTable, "GenMcdMakeCurrent: mcd32.dll not initialized\n");
  1171. bRet = (gpMcdTable->pMCDBindContext)(&pMcdState->McdContext,
  1172. gengc->gwidCurrent.hdc, pwnd);
  1173. //
  1174. // Fake up some of the __GLGENbitmap information. The WNDOBJ is required
  1175. // for clipping of the hardware back buffer. The hdc is required to
  1176. // retrieve drawing data from GDI.
  1177. //
  1178. if (gengc->gc.modes.doubleBufferMode)
  1179. {
  1180. __GLGENbitmap *genBm = gengc->gc.back->bitmap;
  1181. ASSERT_WINCRIT(gengc->pwndLocked);
  1182. genBm->pwnd = gengc->pwndLocked;
  1183. genBm->hdc = gengc->gwidCurrent.hdc;
  1184. }
  1185. #if DBG
  1186. if (!bRet)
  1187. {
  1188. WARNING2("GenMcdMakeCurrent: MCDBindContext failed\n"
  1189. "\tpMcdCx = 0x%08lx, pwnd = 0x%08lx\n",
  1190. &pMcdState->McdContext, pwnd);
  1191. }
  1192. #endif
  1193. return bRet;
  1194. }
  1195. /******************************Public*Routine******************************\
  1196. * GenMcdClear
  1197. *
  1198. * Call MCD driver to clear specified buffers. The buffers are specified by
  1199. * the masked pointed to by pClearMask.
  1200. *
  1201. * There is no function return value, but the function will clear the mask
  1202. * bits of the buffers it successfully cleared.
  1203. *
  1204. * History:
  1205. * 06-Feb-1996 -by- Gilman Wong [gilmanw]
  1206. * Wrote it.
  1207. \**************************************************************************/
  1208. void FASTCALL GenMcdClear(__GLGENcontext *gengc, ULONG *pClearMask)
  1209. {
  1210. RECTL rcl;
  1211. ULONG mask;
  1212. ASSERTOPENGL(gengc->pMcdState, "GenMcdClear: null pMcdState\n");
  1213. //
  1214. // If MCD format supports stencil, include GL_STENCIL_BUFFER_BIT in
  1215. // the mask.
  1216. //
  1217. if (gengc->pMcdState->McdPixelFmt.cStencilBits)
  1218. {
  1219. mask = *pClearMask & (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
  1220. GL_STENCIL_BUFFER_BIT);
  1221. }
  1222. else
  1223. {
  1224. mask = *pClearMask & (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  1225. }
  1226. //
  1227. // This function can assume that MCD entry point table is already
  1228. // initialized as we cannot get here without MCD already having been
  1229. // called.
  1230. //
  1231. ASSERTOPENGL(gpMcdTable, "GenMcdClear: mcd32.dll not initialized\n");
  1232. if ( mask )
  1233. {
  1234. GLGENwindow *pwnd = gengc->pwndLocked;
  1235. //
  1236. // Determine the clear rectangle. If there is any window clipping
  1237. // or scissoring, the driver will have to handle it.
  1238. //
  1239. rcl.left = 0;
  1240. rcl.top = 0;
  1241. rcl.right = pwnd->rclClient.right - pwnd->rclClient.left;
  1242. rcl.bottom = pwnd->rclClient.bottom - pwnd->rclClient.top;
  1243. if ((rcl.left != rcl.right) && (rcl.top != rcl.bottom))
  1244. {
  1245. //
  1246. // Before calling MCD to draw, flush state.
  1247. //
  1248. vFlushDirtyState(gengc);
  1249. if ( (gpMcdTable->pMCDClear)(&gengc->pMcdState->McdContext, rcl,
  1250. mask) )
  1251. {
  1252. //
  1253. // Successful, so clear the bits of the buffers we
  1254. // handled.
  1255. //
  1256. *pClearMask &= ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  1257. //
  1258. // Stencil buffer is supplied by generic if MCD does not
  1259. // support it. Therefore, clear this bit if and only if
  1260. // supported by MCD.
  1261. //
  1262. if (gengc->pMcdState->McdPixelFmt.cStencilBits)
  1263. *pClearMask &= ~GL_STENCIL_BUFFER_BIT;
  1264. }
  1265. }
  1266. }
  1267. }
  1268. /******************************Public*Routine******************************\
  1269. * GenMcdCopyPixels
  1270. *
  1271. * Copy span scanline buffer to/from display. Direction is determined by
  1272. * the flag bIn (if bIn is TRUE, copy from color span buffer to display;
  1273. * otherwise, copy from display to color span buffer).
  1274. *
  1275. * History:
  1276. * 14-Feb-1996 -by- Gilman Wong [gilmanw]
  1277. * Wrote it.
  1278. \**************************************************************************/
  1279. void GenMcdCopyPixels(__GLGENcontext *gengc, __GLcolorBuffer *cfb,
  1280. GLint x, GLint y, GLint cx, BOOL bIn)
  1281. {
  1282. GENMCDSTATE *pMcdState;
  1283. GENMCDSURFACE *pMcdSurf;
  1284. ULONG ulType;
  1285. ASSERTOPENGL(gengc->pMcdState, "GenMcdCopyPixels: null pMcdState\n");
  1286. //
  1287. // This function can assume that MCD entry point table is already
  1288. // initialized as we cannot get here without MCD already having been
  1289. // called.
  1290. //
  1291. ASSERTOPENGL(gpMcdTable, "GenMcdCopyPixels: mcd32.dll not initialized\n");
  1292. pMcdState = gengc->pMcdState;
  1293. pMcdSurf = pMcdState->pMcdSurf;
  1294. //
  1295. // Clip the length of the span to the scanline buffer size.
  1296. //
  1297. //!!!mcd -- should we just enforce the buffer limit?
  1298. //cx = min(cx, MCD_MAX_SCANLINE);
  1299. #if DBG
  1300. if (cx > gengc->gc.constants.width)
  1301. WARNING2("GenMcdCopyPixels: cx (%ld) bigger than window width (%ld)\n", cx, gengc->gc.constants.width);
  1302. ASSERTOPENGL(cx <= MCD_MAX_SCANLINE, "GenMcdCopyPixels: cx exceeds buffer width\n");
  1303. #endif
  1304. //
  1305. // Convert screen coordinates to window coordinates.
  1306. //
  1307. if (cfb == gengc->gc.front)
  1308. {
  1309. ulType = MCDSPAN_FRONT;
  1310. x -= gengc->gc.frontBuffer.buf.xOrigin;
  1311. y -= gengc->gc.frontBuffer.buf.yOrigin;
  1312. }
  1313. else
  1314. {
  1315. ulType = MCDSPAN_BACK;
  1316. x -= gengc->gc.backBuffer.buf.xOrigin;
  1317. y -= gengc->gc.backBuffer.buf.yOrigin;
  1318. }
  1319. //
  1320. // If bIn, copy from the scanline buffer to the MCD buffer.
  1321. // Otherwise, copy from the MCD buffer into the scanline buffer.
  1322. //
  1323. if ( bIn )
  1324. {
  1325. if ( !(gpMcdTable->pMCDWriteSpan)(&pMcdState->McdContext,
  1326. pMcdSurf->McdColorBuf.pv,
  1327. x, y, cx, ulType) )
  1328. {
  1329. WARNING3("GenMcdCopyPixels: MCDWriteSpan failed (%ld, %ld) %ld\n", x, y, cx);
  1330. }
  1331. }
  1332. else
  1333. {
  1334. if ( !(gpMcdTable->pMCDReadSpan)(&pMcdState->McdContext,
  1335. pMcdSurf->McdColorBuf.pv,
  1336. x, y, cx, ulType) )
  1337. {
  1338. WARNING3("GenMcdCopyPixels: MCDReadSpan failed (%ld, %ld) %ld\n", x, y, cx);
  1339. }
  1340. }
  1341. }
  1342. /******************************Public*Routine******************************\
  1343. * GenMcdUpdateRenderState
  1344. *
  1345. * Update MCD render state from the OpenGL state.
  1346. *
  1347. * This call only adds a state structure to the current state command.
  1348. * It is assumed that the caller has already called MCDBeginState and
  1349. * will call MCDFlushState.
  1350. *
  1351. * History:
  1352. * 08-Feb-1996 -by- Gilman Wong [gilmanw]
  1353. * Wrote it.
  1354. \**************************************************************************/
  1355. void FASTCALL GenMcdUpdateRenderState(__GLGENcontext *gengc)
  1356. {
  1357. __GLcontext *gc = &gengc->gc;
  1358. GENMCDSTATE *pMcdState = gengc->pMcdState;
  1359. MCDRENDERSTATE McdRenderState;
  1360. ASSERTOPENGL(gengc->pMcdState, "GenMcdUpdateRenderState: null pMcdState\n");
  1361. //
  1362. // This function can assume that MCD entry point table is already
  1363. // initialized as we cannot get here without MCD already having been
  1364. // called.
  1365. //
  1366. ASSERTOPENGL(gpMcdTable, "GenMcdUpdateRenderState: mcd32.dll not initialized\n");
  1367. //
  1368. // Compute MCD state from the current OpenGL context state.
  1369. //
  1370. //
  1371. // -=<< State Enables >>=-
  1372. //
  1373. McdRenderState.enables = gc->state.enables.general;
  1374. //
  1375. // -=<< Texture State >>=-
  1376. //
  1377. McdRenderState.textureEnabled = gc->texture.textureEnabled;
  1378. //
  1379. // -=<< Fog State >>=-
  1380. //
  1381. *((__GLcolor *) &McdRenderState.fogColor) = gc->state.fog.color;
  1382. McdRenderState.fogIndex = gc->state.fog.index;
  1383. McdRenderState.fogDensity = gc->state.fog.density;
  1384. McdRenderState.fogStart = gc->state.fog.start;
  1385. McdRenderState.fogEnd = gc->state.fog.end;
  1386. McdRenderState.fogMode = gc->state.fog.mode;
  1387. //
  1388. // -=<< Shading Model State >>=-
  1389. //
  1390. McdRenderState.shadeModel = gc->state.light.shadingModel;
  1391. //
  1392. // -=<< Point Drawing State >>=-
  1393. //
  1394. McdRenderState.pointSize = gc->state.point.requestedSize;
  1395. //
  1396. // -=<< Line Drawing State >>=-
  1397. //
  1398. McdRenderState.lineWidth = gc->state.line.requestedWidth;
  1399. McdRenderState.lineStipplePattern = gc->state.line.stipple;
  1400. McdRenderState.lineStippleRepeat = gc->state.line.stippleRepeat;
  1401. //
  1402. // -=<< Polygon Drawing State >>=-
  1403. //
  1404. McdRenderState.cullFaceMode = gc->state.polygon.cull;
  1405. McdRenderState.frontFace = gc->state.polygon.frontFaceDirection;
  1406. McdRenderState.polygonModeFront = gc->state.polygon.frontMode;
  1407. McdRenderState.polygonModeBack = gc->state.polygon.backMode;
  1408. memcpy(&McdRenderState.polygonStipple, &gc->state.polygonStipple.stipple,
  1409. sizeof(McdRenderState.polygonStipple));
  1410. McdRenderState.zOffsetFactor = gc->state.polygon.factor;
  1411. McdRenderState.zOffsetUnits = gc->state.polygon.units;
  1412. //
  1413. // -=<< Stencil Test State >>=-
  1414. //
  1415. McdRenderState.stencilTestFunc = gc->state.stencil.testFunc;
  1416. McdRenderState.stencilMask = (USHORT) gc->state.stencil.mask;
  1417. McdRenderState.stencilRef = (USHORT) gc->state.stencil.reference;
  1418. McdRenderState.stencilFail = gc->state.stencil.fail;
  1419. McdRenderState.stencilDepthFail = gc->state.stencil.depthFail;
  1420. McdRenderState.stencilDepthPass = gc->state.stencil.depthPass;
  1421. //
  1422. // -=<< Alpha Test State >>=-
  1423. //
  1424. McdRenderState.alphaTestFunc = gc->state.raster.alphaFunction;
  1425. McdRenderState.alphaTestRef = gc->state.raster.alphaReference;
  1426. //
  1427. // -=<< Depth Test State >>=-
  1428. //
  1429. McdRenderState.depthTestFunc = gc->state.depth.testFunc;
  1430. //
  1431. // -=<< Blend State >>=-
  1432. //
  1433. McdRenderState.blendSrc = gc->state.raster.blendSrc;
  1434. McdRenderState.blendDst = gc->state.raster.blendDst;
  1435. //
  1436. // -=<< Logic Op State >>=-
  1437. //
  1438. McdRenderState.logicOpMode = gc->state.raster.logicOp;
  1439. //
  1440. // -=<< Frame Buffer Control State >>=-
  1441. //
  1442. McdRenderState.drawBuffer = gc->state.raster.drawBuffer;
  1443. McdRenderState.indexWritemask = gc->state.raster.writeMask;
  1444. McdRenderState.colorWritemask[0] = gc->state.raster.rMask;
  1445. McdRenderState.colorWritemask[1] = gc->state.raster.gMask;
  1446. McdRenderState.colorWritemask[2] = gc->state.raster.bMask;
  1447. McdRenderState.colorWritemask[3] = gc->state.raster.aMask;
  1448. McdRenderState.depthWritemask = gc->state.depth.writeEnable;
  1449. // To be consistent, we will scale the clear color to whatever
  1450. // the MCD driver specified:
  1451. McdRenderState.colorClearValue.r = gc->state.raster.clear.r * gc->redVertexScale;
  1452. McdRenderState.colorClearValue.g = gc->state.raster.clear.g * gc->greenVertexScale;
  1453. McdRenderState.colorClearValue.b = gc->state.raster.clear.b * gc->blueVertexScale;
  1454. McdRenderState.colorClearValue.a = gc->state.raster.clear.a * gc->alphaVertexScale;
  1455. McdRenderState.indexClearValue = gc->state.raster.clearIndex;
  1456. McdRenderState.stencilClearValue = (USHORT) gc->state.stencil.clear;
  1457. McdRenderState.depthClearValue = (MCDDOUBLE) (gc->state.depth.clear *
  1458. gengc->genAccel.zDevScale);
  1459. //
  1460. // -=<< Lighting >>=-
  1461. //
  1462. McdRenderState.twoSided = gc->state.light.model.twoSided;
  1463. //
  1464. // -=<< Clipping Control >>=-
  1465. //
  1466. memset(McdRenderState.userClipPlanes, 0, sizeof(McdRenderState.userClipPlanes));
  1467. {
  1468. ULONG i, mask, numClipPlanes;
  1469. //
  1470. // Number of user defined clip planes should match. However,
  1471. // rather than assume this, let's take the min and be robust.
  1472. //
  1473. ASSERTOPENGL(sizeof(__GLcoord) == sizeof(MCDCOORD),
  1474. "GenMcdUpdateRenderState: coord struct mismatch\n");
  1475. ASSERTOPENGL(MCD_MAX_USER_CLIP_PLANES == gc->constants.numberOfClipPlanes,
  1476. "GenMcdUpdateRenderState: num clip planes mismatch\n");
  1477. numClipPlanes = min(MCD_MAX_USER_CLIP_PLANES, gc->constants.numberOfClipPlanes);
  1478. for (i = 0, mask = 1; i < numClipPlanes; i++, mask <<= 1)
  1479. {
  1480. if (mask & gc->state.enables.clipPlanes)
  1481. {
  1482. McdRenderState.userClipPlanes[i] =
  1483. *(MCDCOORD *)&gc->state.transform.eyeClipPlanes[i];
  1484. }
  1485. }
  1486. }
  1487. //
  1488. // -=<< Hints >>=-
  1489. //
  1490. McdRenderState.perspectiveCorrectionHint = gc->state.hints.perspectiveCorrection;
  1491. McdRenderState.pointSmoothHint = gc->state.hints.pointSmooth;
  1492. McdRenderState.lineSmoothHint = gc->state.hints.lineSmooth;
  1493. McdRenderState.polygonSmoothHint = gc->state.hints.polygonSmooth;
  1494. McdRenderState.fogHint = gc->state.hints.fog;
  1495. //
  1496. // Now that the complete MCD state is computed, add it to the state cmd.
  1497. //
  1498. (gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  1499. MCD_RENDER_STATE,
  1500. &McdRenderState,
  1501. sizeof(McdRenderState));
  1502. }
  1503. /******************************Public*Routine******************************\
  1504. * GenMcdViewport
  1505. *
  1506. * Set the viewport from the OpenGL state.
  1507. *
  1508. * History:
  1509. * 09-Feb-1996 -by- Gilman Wong [gilmanw]
  1510. * Wrote it.
  1511. \**************************************************************************/
  1512. void FASTCALL GenMcdViewport(__GLGENcontext *gengc)
  1513. {
  1514. MCDVIEWPORT mcdVP;
  1515. ASSERTOPENGL(gengc->pMcdState, "GenMcdViewport: null pMcdState\n");
  1516. //
  1517. // This function can assume that MCD entry point table is already
  1518. // initialized as we cannot get here without MCD already having been
  1519. // called.
  1520. //
  1521. ASSERTOPENGL(gpMcdTable, "GenMcdViewport: mcd32.dll not initialized\n");
  1522. //
  1523. // We can copy directly from &viewport.xScale to a MCDVIEWPORT because the
  1524. // structures are the same. To be safe, assert the structure ordering.
  1525. //
  1526. ASSERTOPENGL(
  1527. offsetof(MCDVIEWPORT, xCenter) ==
  1528. (offsetof(__GLviewport, xCenter) - offsetof(__GLviewport, xScale))
  1529. && offsetof(MCDVIEWPORT, yCenter) ==
  1530. (offsetof(__GLviewport, yCenter) - offsetof(__GLviewport, xScale))
  1531. && offsetof(MCDVIEWPORT, zCenter) ==
  1532. (offsetof(__GLviewport, zCenter) - offsetof(__GLviewport, xScale))
  1533. && offsetof(MCDVIEWPORT, yScale) ==
  1534. (offsetof(__GLviewport, yScale) - offsetof(__GLviewport, xScale))
  1535. && offsetof(MCDVIEWPORT, zScale) ==
  1536. (offsetof(__GLviewport, zScale) - offsetof(__GLviewport, xScale)),
  1537. "GenMcdViewport: structure mismatch\n");
  1538. memcpy(&mcdVP.xScale, &gengc->gc.state.viewport.xScale,
  1539. sizeof(MCDVIEWPORT));
  1540. (gpMcdTable->pMCDSetViewport)(&gengc->pMcdState->McdContext,
  1541. gengc->pMcdState->McdCmdBatch.pv, &mcdVP);
  1542. }
  1543. /******************************Public*Routine******************************\
  1544. * GenMcdScissor
  1545. *
  1546. * Set the scissor rectangle from the OpenGL state.
  1547. *
  1548. * History:
  1549. * 06-Mar-1996 -by- Gilman Wong [gilmanw]
  1550. * Wrote it.
  1551. \**************************************************************************/
  1552. static void FASTCALL vGetScissor(__GLGENcontext *gengc, RECTL *prcl)
  1553. {
  1554. prcl->left = gengc->gc.state.scissor.scissorX;
  1555. prcl->right = gengc->gc.state.scissor.scissorX + gengc->gc.state.scissor.scissorWidth;
  1556. if (gengc->gc.constants.yInverted)
  1557. {
  1558. prcl->bottom = gengc->gc.constants.height -
  1559. gengc->gc.state.scissor.scissorY;
  1560. prcl->top = gengc->gc.constants.height -
  1561. (gengc->gc.state.scissor.scissorY + gengc->gc.state.scissor.scissorHeight);
  1562. }
  1563. else
  1564. {
  1565. prcl->top = gengc->gc.state.scissor.scissorY;
  1566. prcl->bottom = gengc->gc.state.scissor.scissorY + gengc->gc.state.scissor.scissorHeight;
  1567. }
  1568. }
  1569. void FASTCALL GenMcdScissor(__GLGENcontext *gengc)
  1570. {
  1571. BOOL bEnabled;
  1572. RECTL rcl;
  1573. ASSERTOPENGL(gengc->pMcdState, "GenMcdScissor: null pMcdState\n");
  1574. //
  1575. // This function can assume that MCD entry point table is already
  1576. // initialized as we cannot get here without MCD already having been
  1577. // called.
  1578. //
  1579. ASSERTOPENGL(gpMcdTable, "GenMcdScissor: mcd32.dll not initialized\n");
  1580. vGetScissor(gengc, &rcl);
  1581. bEnabled = (gengc->gc.state.enables.general & __GL_SCISSOR_TEST_ENABLE)
  1582. ? TRUE : FALSE;
  1583. (gpMcdTable->pMCDSetScissorRect)(&gengc->pMcdState->McdContext, &rcl,
  1584. bEnabled);
  1585. }
  1586. /******************************Public*Routine******************************\
  1587. * GenMcdUpdateScissorState
  1588. *
  1589. * Update MCD scissor state from the OpenGL state.
  1590. *
  1591. * This call only adds a state structure to the current state command.
  1592. * It is assumed that the caller has already called MCDBeginState and
  1593. * will call MCDFlushState.
  1594. *
  1595. * This is similar to but not quite the same as GenMcdScissor. The
  1596. * GenMcdScissor only sets the scissor rect in the MCDSRV32.DLL to
  1597. * compute the scissored clip list it maintains. This call is used
  1598. * to update the scissor rectangle state in the (MCD) display driver.
  1599. *
  1600. * History:
  1601. * 27-May-1996 -by- Gilman Wong [gilmanw]
  1602. * Wrote it.
  1603. \**************************************************************************/
  1604. void FASTCALL GenMcdUpdateScissorState(__GLGENcontext *gengc)
  1605. {
  1606. __GLcontext *gc = &gengc->gc;
  1607. GENMCDSTATE *pMcdState = gengc->pMcdState;
  1608. RECTL rcl;
  1609. ASSERTOPENGL(gengc->pMcdState, "GenMcdUpdateScissorState: null pMcdState\n");
  1610. //
  1611. // This function can assume that MCD entry point table is already
  1612. // initialized as we cannot get here without MCD already having been
  1613. // called.
  1614. //
  1615. ASSERTOPENGL(gpMcdTable, "GenMcdUpdateScissorState: mcd32.dll not initialized\n");
  1616. //
  1617. // Get the scissor rect.
  1618. //
  1619. vGetScissor(gengc, &rcl);
  1620. //
  1621. // Add MCDPIXELSTATE to the state cmd.
  1622. //
  1623. (gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  1624. MCD_SCISSOR_RECT_STATE,
  1625. &rcl,
  1626. sizeof(rcl));
  1627. }
  1628. /******************************Public*Routine******************************\
  1629. * GenMcdUpdateTexEnvState
  1630. *
  1631. * Update MCD texture environment state from the OpenGL state.
  1632. *
  1633. * This call only adds a state structure to the current state command.
  1634. * It is assumed that the caller has already called MCDBeginState and
  1635. * will call MCDFlushState.
  1636. *
  1637. * History:
  1638. * 21-Oct-1996 -by- Gilman Wong [gilmanw]
  1639. * Wrote it.
  1640. \**************************************************************************/
  1641. void FASTCALL GenMcdUpdateTexEnvState(__GLGENcontext *gengc)
  1642. {
  1643. __GLcontext *gc = &gengc->gc;
  1644. GENMCDSTATE *pMcdState = gengc->pMcdState;
  1645. MCDTEXENVSTATE McdTexEnvState;
  1646. ASSERTOPENGL(gengc->pMcdState, "GenMcdUpdateTexEnvState: "
  1647. "null pMcdState\n");
  1648. //
  1649. // This function can assume that MCD entry point table is already
  1650. // initialized as we cannot get here without MCD already having been
  1651. // called.
  1652. //
  1653. ASSERTOPENGL(gpMcdTable, "GenMcdUpdateTexEnvState: "
  1654. "mcd32.dll not initialized\n");
  1655. //
  1656. // The texture environment array should have been initialized in
  1657. // __glEarlyInitTextureState, but it does not have an error return
  1658. // so it is possible that the array is NULL.
  1659. //
  1660. if (!gengc->gc.state.texture.env)
  1661. {
  1662. WARNING("GenMcdUpdateTexEnvState: null texture environment\n");
  1663. return;
  1664. }
  1665. //
  1666. // There is only one texture environment per-context.
  1667. //
  1668. // If multiple textures are added to a future version of OpenGL,
  1669. // then we can define a new state structure for each new texture.
  1670. // Or we can add a separate MCDTEXENVSTATE structure to the state
  1671. // batch for each supported texture environment. The first structure
  1672. // is for the first environment, the second structure is for the
  1673. // second environment, etc. The driver can ignore any structures
  1674. // over the number of texture environments it supports. Of course,
  1675. // these are just suggestions. Depending on how multiple textures
  1676. // are spec'd, we might have to do something totally different.
  1677. //
  1678. McdTexEnvState.texEnvMode = gengc->gc.state.texture.env[0].mode;
  1679. *((__GLcolor *) &McdTexEnvState.texEnvColor) = gengc->gc.state.texture.env[0].color;
  1680. //
  1681. // Add MCDPIXELSTATE to the state cmd.
  1682. //
  1683. (gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  1684. MCD_TEXENV_STATE,
  1685. &McdTexEnvState,
  1686. sizeof(McdTexEnvState));
  1687. }
  1688. /******************************Public*Routine******************************\
  1689. * GenMcdDrawPrim
  1690. *
  1691. * Draw the primitives in the POLYARRAY/POLYDATA array pointed to by pa.
  1692. * The primitives are chained together as a linked list terminated by a
  1693. * NULL. The return value is a pointer to the first unhandled primitive
  1694. * (NULL if the entire chain is successfully processed).
  1695. *
  1696. * Returns:
  1697. * NULL if entire batch is processed; otherwise, return value is a pointer
  1698. * to the unhandled portion of the chain.
  1699. *
  1700. * History:
  1701. * 09-Feb-1996 -by- Gilman Wong [gilmanw]
  1702. * Wrote it.
  1703. \**************************************************************************/
  1704. POLYARRAY * FASTCALL GenMcdDrawPrim(__GLGENcontext *gengc, POLYARRAY *pa)
  1705. {
  1706. GENMCDSTATE *pMcdState = gengc->pMcdState;
  1707. int levels;
  1708. LPDIRECTDRAWSURFACE *pdds;
  1709. ASSERTOPENGL(gengc->pMcdState, "GenMcdDrawPrim: null pMcdState\n");
  1710. //
  1711. // This function can assume that MCD entry point table is already
  1712. // initialized as we cannot get here without MCD already having been
  1713. // called.
  1714. //
  1715. ASSERTOPENGL(gpMcdTable, "GenMcdDrawPrim: mcd32.dll not initialized\n");
  1716. #if DBG
  1717. {
  1718. LONG lOffset;
  1719. lOffset = (LONG) ((BYTE *) pa - (BYTE *) pMcdState->pMcdPrimBatch->pv);
  1720. ASSERTOPENGL(
  1721. (lOffset >= 0) &&
  1722. (lOffset < (LONG) pMcdState->pMcdPrimBatch->size),
  1723. "GenMcdDrawPrim: pa not in shared mem window\n");
  1724. }
  1725. #endif
  1726. //
  1727. // Before calling MCD to draw, flush state.
  1728. //
  1729. vFlushDirtyState(gengc);
  1730. #ifdef AUTOMATIC_SURF_LOCK
  1731. levels = gengc->gc.texture.ddtex.levels;
  1732. if (levels > 0 &&
  1733. gengc->gc.texture.ddtex.texobj.loadKey != 0)
  1734. {
  1735. pdds = gengc->gc.texture.ddtex.pdds;
  1736. }
  1737. else
  1738. #endif
  1739. {
  1740. levels = 0;
  1741. pdds = NULL;
  1742. }
  1743. return (POLYARRAY *)
  1744. (gpMcdTable->pMCDProcessBatch)(&pMcdState->McdContext,
  1745. pMcdState->pMcdPrimBatch->pv,
  1746. pMcdState->pMcdPrimBatch->size,
  1747. (PVOID) pa,
  1748. levels, pdds);
  1749. }
  1750. /******************************Public*Routine******************************\
  1751. * GenMcdSwapBatch
  1752. *
  1753. * If the MCD driver uses DMA, then as part of context creation TWO vertex
  1754. * buffers we allocated so that we could ping-pong or double buffer between
  1755. * the two buffers (i.e., while the MCD driver is busy processing the
  1756. * data in one vertex buffer, OpenGL can start filling the other vertex
  1757. * buffer).
  1758. *
  1759. * This function switches the MCD state and OpenGL context to the other
  1760. * buffer. If the new buffer is still being processed by the MCD driver,
  1761. * we will periodically poll the status of the buffer until it becomes
  1762. * available.
  1763. *
  1764. * History:
  1765. * 08-Mar-1996 -by- Gilman Wong [gilmanw]
  1766. * Wrote it.
  1767. \**************************************************************************/
  1768. void FASTCALL GenMcdSwapBatch(__GLGENcontext *gengc)
  1769. {
  1770. GENMCDSTATE *pMcdState = gengc->pMcdState;
  1771. GENMCDBUF *pNewBuf;
  1772. ULONG ulMemStatus;
  1773. ASSERTOPENGL(gengc->pMcdState, "GenMcdSwapBatch: null pMcdState\n");
  1774. ASSERTOPENGL(McdDriverInfo.mcdDriverInfo.drvMemFlags & MCDRV_MEM_DMA,
  1775. "GenMcdSwapBatch: error -- not using DMA\n");
  1776. //
  1777. // This function can assume that MCD entry point table is already
  1778. // initialized as we cannot get here without MCD already having been
  1779. // called.
  1780. //
  1781. ASSERTOPENGL(gpMcdTable, "GenMcdSwapBatch: mcd32.dll not initialized\n");
  1782. //
  1783. // Determine which of McdBuf1 and McdBuf2 is the current buffer and
  1784. // which is the new buffer.
  1785. //
  1786. if (pMcdState->pMcdPrimBatch == &pMcdState->McdBuf1)
  1787. pNewBuf = &pMcdState->McdBuf2;
  1788. else
  1789. pNewBuf = &pMcdState->McdBuf1;
  1790. //
  1791. // Poll memory status of the new buffer until it is available.
  1792. //
  1793. do
  1794. {
  1795. ulMemStatus = (gpMcdTable->pMCDQueryMemStatus)(pNewBuf->pv);
  1796. //
  1797. // If status of the new buffer is MCD_MEM_READY, set it as the
  1798. // current vertex buffer (both in the pMcdState and in the gengc.
  1799. //
  1800. if (ulMemStatus == MCD_MEM_READY)
  1801. {
  1802. pMcdState->pMcdPrimBatch = pNewBuf;
  1803. gengc->gc.vertex.pdBuf = (POLYDATA *) pMcdState->pMcdPrimBatch->pv;
  1804. }
  1805. else if (ulMemStatus == MCD_MEM_INVALID)
  1806. {
  1807. //
  1808. // This should not be possible, but to be robust let's handle
  1809. // the case in which the new buffer has somehow become invalid
  1810. // (in other words, "Beware of bad drivers!").
  1811. //
  1812. // We handle this by abandoning double buffering and simply
  1813. // wait for the current buffer to become available again.
  1814. // Not very efficient, but at least we recover gracefully.
  1815. //
  1816. RIP("GenMcdSwapBatch: vertex buffer invalid!\n");
  1817. do
  1818. {
  1819. ulMemStatus = (gpMcdTable->pMCDQueryMemStatus)(pMcdState->pMcdPrimBatch->pv);
  1820. //
  1821. // The current buffer definitely should not become invalid!
  1822. //
  1823. ASSERTOPENGL(ulMemStatus != MCD_MEM_INVALID,
  1824. "GenMcdSwapBatch: current vertex buffer invalid!\n");
  1825. } while (ulMemStatus == MCD_MEM_BUSY);
  1826. }
  1827. } while (ulMemStatus == MCD_MEM_BUSY);
  1828. }
  1829. /******************************Public*Routine******************************\
  1830. * GenMcdSwapBuffers
  1831. *
  1832. * Invoke the MCD swap buffers command.
  1833. *
  1834. * Returns:
  1835. * TRUE if successful, FALSE otherwise.
  1836. *
  1837. * History:
  1838. * 19-Feb-1996 -by- Gilman Wong [gilmanw]
  1839. * Wrote it.
  1840. \**************************************************************************/
  1841. BOOL FASTCALL GenMcdSwapBuffers(HDC hdc, GLGENwindow *pwnd)
  1842. {
  1843. BOOL bRet = FALSE;
  1844. MCDCONTEXT McdContextTmp;
  1845. //
  1846. // This function can assume that MCD entry point table is already
  1847. // initialized as we cannot get here without MCD already having been
  1848. // called.
  1849. //
  1850. ASSERTOPENGL(gpMcdTable, "GenMcdSwapBuffers: mcd32.dll not initialized\n");
  1851. McdContextTmp.hdc = hdc;
  1852. McdContextTmp.hMCDContext = NULL;
  1853. McdContextTmp.dwMcdWindow = pwnd->dwMcdWindow;
  1854. bRet = (gpMcdTable->pMCDSwap)(&McdContextTmp, 0);
  1855. return bRet;
  1856. }
  1857. /******************************Public*Routine******************************\
  1858. * GenMcdResizeBuffers
  1859. *
  1860. * Resize the buffers (front, back, and depth) associated with the MCD
  1861. * context bound to the specified GL context.
  1862. *
  1863. * Returns:
  1864. * TRUE if successful, FALSE otherwise.
  1865. *
  1866. * Note: If this functions fails, then MCD drawing for the MCD context
  1867. * will fail. Other MCD contexts are unaffected.
  1868. *
  1869. * History:
  1870. * 20-Feb-1996 -by- Gilman Wong [gilmanw]
  1871. * Wrote it.
  1872. \**************************************************************************/
  1873. BOOL FASTCALL GenMcdResizeBuffers(__GLGENcontext *gengc)
  1874. {
  1875. BOOL bRet = FALSE;
  1876. ASSERTOPENGL(gengc->pMcdState, "GenMcdResizeBuffers: null pMcdState\n");
  1877. //
  1878. // This function can assume that MCD entry point table is already
  1879. // initialized as we cannot get here without MCD already having been
  1880. // called.
  1881. //
  1882. ASSERTOPENGL(gpMcdTable, "GenMcdResizeBuffers: mcd32.dll not initialized\n");
  1883. bRet = (gpMcdTable->pMCDAllocBuffers)(&gengc->pMcdState->McdContext,
  1884. &gengc->pwndLocked->rclClient);
  1885. return bRet;
  1886. }
  1887. /******************************Public*Routine******************************\
  1888. * GenMcdUpdateBufferInfo
  1889. *
  1890. * This function must be called on every screen access start to synchronize
  1891. * the GENMCDSURFACE to the current framebuffer pointer and stride.
  1892. *
  1893. * If we have direct access to any of the MCD buffers (front, back, depth),
  1894. * then setup pointers to the buffer and set flags indicating that they are
  1895. * accessible.
  1896. *
  1897. * Otherwise, mark them as inaccessible (which will force us to use
  1898. * MCDReadSpan or MCDWriteSpan to access the buffers).
  1899. *
  1900. * History:
  1901. * 20-Feb-1996 -by- Gilman Wong [gilmanw]
  1902. * Wrote it.
  1903. \**************************************************************************/
  1904. BOOL FASTCALL GenMcdUpdateBufferInfo(__GLGENcontext *gengc)
  1905. {
  1906. BOOL bRet = FALSE;
  1907. __GLcontext *gc = (__GLcontext *) gengc;
  1908. __GLGENbuffers *buffers = gengc->pwndLocked->buffers;
  1909. GENMCDSTATE *pMcdState = gengc->pMcdState;
  1910. MCDRECTBUFFERS McdBuffers;
  1911. BOOL bForceValidate = FALSE;
  1912. //
  1913. // This function can assume that MCD entry point table is already
  1914. // initialized as we cannot get here without MCD already having been
  1915. // called.
  1916. //
  1917. ASSERTOPENGL(gpMcdTable, "GenMcdUpdateBufferInfo: mcd32.dll not initialized\n");
  1918. //
  1919. // Does the flag in pMcdState indicate that a pick should be forced?
  1920. // This is required, for example, for the first batch after an MCD
  1921. // context has been made current.
  1922. //
  1923. if (pMcdState->mcdFlags & MCD_STATE_FORCEPICK)
  1924. {
  1925. bForceValidate = TRUE;
  1926. pMcdState->mcdFlags &= ~MCD_STATE_FORCEPICK;
  1927. }
  1928. //
  1929. // This is the currently active context. Set the pointer in the
  1930. // shared surface info.
  1931. //
  1932. buffers->pMcdState = pMcdState;
  1933. #ifdef MCD95
  1934. //
  1935. // Set the request flags.
  1936. //
  1937. McdBuffers.mcdRequestFlags = MCDBUF_REQ_MCDBUFINFO;
  1938. #endif
  1939. if (gengc->dwCurrentFlags & GLSURF_DIRECTDRAW)
  1940. {
  1941. // Nothing to do
  1942. }
  1943. else if ((gengc->fsLocks & LOCKFLAG_FRONT_BUFFER)
  1944. && (gpMcdTable->pMCDGetBuffers)(&pMcdState->McdContext, &McdBuffers))
  1945. {
  1946. BYTE *pbVideoBase;
  1947. // If we're in this code block it shouldn't be possible
  1948. // to have the DD_DEPTH lock since that should only
  1949. // occur if the current surface is a DDraw surface.
  1950. ASSERTOPENGL((gengc->fsLocks & LOCKFLAG_DD_DEPTH) == 0,
  1951. "DD_DEPTH lock unexpected\n");
  1952. #ifdef MCD95
  1953. pbVideoBase = (BYTE *) McdBuffers.pvFrameBuf;
  1954. #else
  1955. //
  1956. // In order to compute the buffer pointers from the offsets returned by
  1957. // MCDGetBuffers, we need to know the frame buffer pointer.
  1958. // This implies direct screen access must be enabled.
  1959. //
  1960. if (gengc->pgddsFront != NULL)
  1961. {
  1962. pbVideoBase = (BYTE *)GLSCREENINFO->gdds.ddsd.lpSurface;
  1963. }
  1964. #endif
  1965. //
  1966. // Front buffer.
  1967. //
  1968. if (McdBuffers.mcdFrontBuf.bufFlags & MCDBUF_ENABLED)
  1969. {
  1970. gc->frontBuffer.buf.xOrigin = gengc->pwndLocked->rclClient.left;
  1971. gc->frontBuffer.buf.yOrigin = gengc->pwndLocked->rclClient.top;
  1972. //
  1973. // Since clipping is in screen coordinates, offset buffer pointer
  1974. // by the buffer origin.
  1975. //
  1976. gc->frontBuffer.buf.base =
  1977. (PVOID) (pbVideoBase + McdBuffers.mcdFrontBuf.bufOffset
  1978. - (McdBuffers.mcdFrontBuf.bufStride * gc->frontBuffer.buf.yOrigin)
  1979. - (gc->frontBuffer.buf.xOrigin * ((gengc->gsurf.pfd.cColorBits + 7) >> 3)));
  1980. gc->frontBuffer.buf.outerWidth = McdBuffers.mcdFrontBuf.bufStride;
  1981. gc->frontBuffer.buf.flags |= DIB_FORMAT;
  1982. }
  1983. else
  1984. {
  1985. gc->frontBuffer.buf.xOrigin = 0;
  1986. gc->frontBuffer.buf.yOrigin = 0;
  1987. gc->frontBuffer.buf.base = NULL;
  1988. gc->frontBuffer.buf.flags &= ~DIB_FORMAT;
  1989. }
  1990. //
  1991. // Back buffer.
  1992. //
  1993. if (McdBuffers.mcdBackBuf.bufFlags & MCDBUF_ENABLED)
  1994. {
  1995. gc->backBuffer.buf.xOrigin = gengc->pwndLocked->rclClient.left;
  1996. gc->backBuffer.buf.yOrigin = gengc->pwndLocked->rclClient.top;
  1997. //
  1998. // Since clipping is in screen coordinates, offset buffer pointer
  1999. // by the buffer origin.
  2000. //
  2001. gc->backBuffer.buf.base =
  2002. (PVOID) (pbVideoBase + McdBuffers.mcdBackBuf.bufOffset
  2003. - (McdBuffers.mcdBackBuf.bufStride * gc->backBuffer.buf.yOrigin)
  2004. - (gc->backBuffer.buf.xOrigin * ((gengc->gsurf.pfd.cColorBits + 7) >> 3)));
  2005. gc->backBuffer.buf.outerWidth = McdBuffers.mcdBackBuf.bufStride;
  2006. gc->backBuffer.buf.flags |= DIB_FORMAT;
  2007. }
  2008. else
  2009. {
  2010. gc->backBuffer.buf.xOrigin = 0;
  2011. gc->backBuffer.buf.yOrigin = 0;
  2012. gc->backBuffer.buf.base = (PVOID) NULL;
  2013. gc->backBuffer.buf.flags &= ~DIB_FORMAT;
  2014. }
  2015. if (McdBuffers.mcdBackBuf.bufFlags & MCDBUF_NOCLIP)
  2016. gc->backBuffer.buf.flags |= NO_CLIP;
  2017. else
  2018. gc->backBuffer.buf.flags &= ~NO_CLIP;
  2019. UpdateSharedBuffer(&buffers->backBuffer , &gc->backBuffer.buf);
  2020. //
  2021. // Depth buffer.
  2022. //
  2023. //!!!mcd -- No depth buffer clipping code, so if we have to clip
  2024. //!!!mcd depth buffer we need to revert back to span code.
  2025. if ((McdBuffers.mcdDepthBuf.bufFlags & MCDBUF_ENABLED) &&
  2026. (McdBuffers.mcdDepthBuf.bufFlags & MCDBUF_NOCLIP))
  2027. {
  2028. gc->depthBuffer.buf.xOrigin = 0;
  2029. gc->depthBuffer.buf.yOrigin = 0;
  2030. gc->depthBuffer.buf.base =
  2031. (PVOID) (pbVideoBase + McdBuffers.mcdDepthBuf.bufOffset);
  2032. //
  2033. // Depth code expects stride as a pixel count, not a byte count.
  2034. //
  2035. gc->depthBuffer.buf.outerWidth =
  2036. McdBuffers.mcdDepthBuf.bufStride /
  2037. ((pMcdState->McdPixelFmt.cDepthBufferBits + 7) >> 3);
  2038. //!!!mcd dbug -- span code sets element size to 32bit. should we
  2039. //!!!mcd dbug set according to cDepthBits when direct access is used?!?
  2040. }
  2041. else
  2042. {
  2043. //
  2044. // If we ended up here because clipping is required, buffer
  2045. // could still be marked as accessible. We want the state change
  2046. // detection code to treat this as an inaccessible buffer case,
  2047. // so force the flags to 0.
  2048. //
  2049. McdBuffers.mcdDepthBuf.bufFlags = 0;
  2050. gc->depthBuffer.buf.xOrigin = 0;
  2051. gc->depthBuffer.buf.yOrigin = 0;
  2052. gc->depthBuffer.buf.base = (PVOID) pMcdState->pDepthSpan;
  2053. //!!!mcd dbug -- always force pick procs if no zbuf access
  2054. //bForceValidate = TRUE;
  2055. }
  2056. UpdateSharedBuffer(&buffers->depthBuffer , &gc->depthBuffer.buf);
  2057. bRet = TRUE;
  2058. }
  2059. else
  2060. {
  2061. //
  2062. // MCDGetBuffers normally shouldn't fail. However, let's gracefully
  2063. // handle this odd case by falling back to the span buffer code.
  2064. //
  2065. gc->frontBuffer.buf.xOrigin = 0;
  2066. gc->frontBuffer.buf.yOrigin = 0;
  2067. gc->frontBuffer.buf.base = (PVOID) NULL;
  2068. gc->frontBuffer.buf.flags &= ~DIB_FORMAT;
  2069. gc->backBuffer.buf.xOrigin = 0;
  2070. gc->backBuffer.buf.yOrigin = 0;
  2071. gc->backBuffer.buf.base = (PVOID) NULL;
  2072. gc->backBuffer.buf.flags &= ~DIB_FORMAT;
  2073. gc->depthBuffer.buf.xOrigin = 0;
  2074. gc->depthBuffer.buf.yOrigin = 0;
  2075. gc->depthBuffer.buf.base = (PVOID) pMcdState->pDepthSpan;
  2076. //
  2077. // Extra paranoid code. Zero out structure in case MCD driver
  2078. // partially initialized McdBuffers.
  2079. //
  2080. memset(&McdBuffers, 0, sizeof(McdBuffers));
  2081. }
  2082. //
  2083. // If state changed (i.e., access to any of the buffers gained or lost),
  2084. // need to force pick procs.
  2085. //
  2086. if ( (pMcdState->McdBuffers.mcdFrontBuf.bufFlags !=
  2087. McdBuffers.mcdFrontBuf.bufFlags)
  2088. || (pMcdState->McdBuffers.mcdBackBuf.bufFlags !=
  2089. McdBuffers.mcdBackBuf.bufFlags)
  2090. || (pMcdState->McdBuffers.mcdDepthBuf.bufFlags !=
  2091. McdBuffers.mcdDepthBuf.bufFlags) )
  2092. {
  2093. bForceValidate = TRUE;
  2094. }
  2095. //
  2096. // Save a copy of current MCD buffers.
  2097. //
  2098. pMcdState->McdBuffers = McdBuffers;
  2099. //
  2100. // If needed, do pick procs.
  2101. //
  2102. if (bForceValidate)
  2103. {
  2104. gc->dirtyMask |= __GL_DIRTY_ALL;
  2105. (*gc->procs.validate)(gc);
  2106. }
  2107. return bRet;
  2108. }
  2109. /******************************Public*Routine******************************\
  2110. * GenMcdSynchronize
  2111. *
  2112. * This function synchronizes to the MCD driver; i.e., it waits until the
  2113. * hardware is ready for direct access to the framebuffer and/or more
  2114. * hardware-accelerated operations. This is needed because some (most?) 2D
  2115. * and 3D accelerator chips do not support simultaneous hardware operations
  2116. * and framebuffer access.
  2117. *
  2118. * This function must be called by any GL API that potentially touches any
  2119. * of the MCD buffers (front, back, or depth) without giving MCD first crack.
  2120. * For example, clears always go to MCDClear before the software clear is
  2121. * given a chance; therefore, glClear does not need to call GenMcdSychronize.
  2122. * On the other hand, glReadPixels does not have an equivalent MCD function
  2123. * so it immediately goes to the software implementation; therefore,
  2124. * glReadPixels does need to call GenMcdSynchronize.
  2125. *
  2126. * History:
  2127. * 20-Mar-1996 -by- Gilman Wong [gilmanw]
  2128. * Wrote it.
  2129. \**************************************************************************/
  2130. void FASTCALL GenMcdSynchronize(__GLGENcontext *gengc)
  2131. {
  2132. GENMCDSTATE *pMcdState = gengc->pMcdState;
  2133. ASSERTOPENGL(gengc->pMcdState, "GenMcdSynchronize: null pMcdState\n");
  2134. //
  2135. // This function can assume that MCD entry point table is already
  2136. // initialized as we cannot get here without MCD already having been
  2137. // called.
  2138. //
  2139. ASSERTOPENGL(gpMcdTable, "GenMcdSynchronize: mcd32.dll not initialized\n");
  2140. //
  2141. // Note: MCDSync returns a BOOL indicating success or failure. This
  2142. // is actually for future expansion. Currently, the function is defined
  2143. // to WAIT until the hardware is ready and then return success. The
  2144. // specification of the function behavior allows us to ignore the return
  2145. // value for now.
  2146. //
  2147. // In the future, we may change this to a query function. In which case
  2148. // we should call this in a while loop. I'd rather not do this at this
  2149. // time though, as it leaves us vulnerable to an infinitely loop problem
  2150. // if we have a bad MCD driver.
  2151. //
  2152. (gpMcdTable->pMCDSync)(&pMcdState->McdContext);
  2153. }
  2154. /******************************Public*Routine******************************\
  2155. * GenMcdConvertContext
  2156. *
  2157. * Convert the context from an MCD-based one to a generic one.
  2158. *
  2159. * This requires creating the buffers, etc. that are required for a generic
  2160. * context and releasing the MCD resources.
  2161. *
  2162. * IMPORTANT NOTE:
  2163. * Because we modify the buffers struct, the WNDOBJ semaphore
  2164. * should be held while calling this function.
  2165. *
  2166. * Returns:
  2167. * TRUE if successful, FALSE otherwise.
  2168. *
  2169. * Side effects:
  2170. * If successful, the MCD surface is freed and the context will use
  2171. * only generic code. However, the gengc->_pMcdState will still point to
  2172. * a valid (but quiescent as gengc->pMcdState is disconnected) GENMCDSTATE
  2173. * structure that needs to be deleted when the GLGENcontext is deleted.
  2174. *
  2175. * If it fails, then the MCD resources are left allocated meaning that
  2176. * we can try to realloc the MCD buffers later. However, for the current
  2177. * batch, drawing may not be possible (presumedly we were called because
  2178. * GenMcdResizeBuffers failed).
  2179. *
  2180. * History:
  2181. * 18-Apr-1996 -by- Gilman Wong [gilmanw]
  2182. * Wrote it.
  2183. \**************************************************************************/
  2184. BOOL FASTCALL GenMcdConvertContext(__GLGENcontext *gengc,
  2185. __GLGENbuffers *buffers)
  2186. {
  2187. BOOL bRet = FALSE;
  2188. __GLcontext *gc = &gengc->gc;
  2189. GENMCDSTATE *pMcdStateSAVE;
  2190. GENMCDSTATE *_pMcdStateSAVE;
  2191. GENMCDSTATE *buffers_pMcdStateSAVE;
  2192. GENMCDSURFACE *pMcdSurfSAVE;
  2193. BOOL bConvertContext, bConvertSurface;
  2194. ASSERTOPENGL(gengc->_pMcdState,
  2195. "GenMcdConvertContext: not an MCD context\n");
  2196. //
  2197. // Do not support conversion if not compatible with generic code.
  2198. //
  2199. if (!(gengc->flags & GENGC_GENERIC_COMPATIBLE_FORMAT))
  2200. return FALSE;
  2201. //
  2202. // Determine if context needs conversion. Do not need to create
  2203. // scanline buffers if already converted.
  2204. //
  2205. if (gengc->flags & GLGEN_MCD_CONVERTED_TO_GENERIC)
  2206. bConvertContext = FALSE;
  2207. else
  2208. bConvertContext = TRUE;
  2209. //
  2210. // Determine if surface needs conversion. Do not need to create
  2211. // the generic shared buffers or destroy MCD surface if already
  2212. // converted.
  2213. //
  2214. if (buffers->flags & GLGENBUF_MCD_LOST)
  2215. bConvertSurface = FALSE;
  2216. else
  2217. bConvertSurface = TRUE;
  2218. //
  2219. // Early out if neither context or surface needs conversion.
  2220. //
  2221. //!!!SP1 -- should be able to early out, but risky for NT4.0
  2222. //if (!bConvertContext && !bConvertSurface)
  2223. //{
  2224. // return TRUE;
  2225. //}
  2226. //
  2227. // Save current MCD context and surface info.
  2228. //
  2229. // Note that we grab the surface info from the buffers struct.
  2230. // The copy in gengc->pMcdState->pMcdSurf is potentially stale
  2231. // (i.e., may point to a surface already deleted by an earlier
  2232. // call to GenMcdConvertContext for a context that shares the
  2233. // same buffers struct).
  2234. //
  2235. // This allows us to use pMcdSurfSAVE as a flag. If it is
  2236. // NULL, we know that the MCD surface has already been deleted.
  2237. //
  2238. pMcdSurfSAVE = buffers->pMcdSurf;
  2239. buffers_pMcdStateSAVE = buffers->pMcdState;
  2240. pMcdStateSAVE = gengc->pMcdState;
  2241. _pMcdStateSAVE = gengc->_pMcdState;
  2242. //
  2243. // First, remove the MCD information from the context and buffers structs.
  2244. //
  2245. buffers->pMcdSurf = NULL;
  2246. buffers->pMcdState = NULL;
  2247. gengc->pMcdState = NULL;
  2248. gengc->_pMcdState = NULL;
  2249. //
  2250. // Create required buffers; initialize buffer info structs.
  2251. //
  2252. if (bConvertContext)
  2253. {
  2254. if (!wglCreateScanlineBuffers(gengc))
  2255. {
  2256. WARNING("GenMcdConvertContext: wglCreateScanlineBuffers failed\n");
  2257. goto GenMcdConvertContext_exit;
  2258. }
  2259. wglInitializeColorBuffers(gengc);
  2260. wglInitializeDepthBuffer(gengc);
  2261. wglInitializePixelCopyFuncs(gengc);
  2262. }
  2263. //
  2264. // *******************************************************************
  2265. // None of the subsequent operations have failure cases, so at this
  2266. // point success is guaranteed. We no longer need to worry about
  2267. // saving current values so that they can be restored in the failure
  2268. // case.
  2269. //
  2270. // If code is added that may fail, it must be added before this point.
  2271. // Otherwise, it is acceptable to add the code afterwards.
  2272. // *******************************************************************
  2273. //
  2274. bRet = TRUE;
  2275. //
  2276. // Invalidate the context's depth buffer.
  2277. //
  2278. if (bConvertContext)
  2279. {
  2280. gc->modes.haveDepthBuffer = GL_FALSE;
  2281. gc->depthBuffer.buf.base = 0;
  2282. gc->depthBuffer.buf.size = 0;
  2283. gc->depthBuffer.buf.outerWidth = 0;
  2284. }
  2285. //
  2286. // Generic backbuffer doesn't care about the WNDOBJ, so connect the
  2287. // backbuffer to the dummy backbuffer WNDOBJ rather than the real one.
  2288. //
  2289. if (gc->modes.doubleBufferMode)
  2290. {
  2291. gc->backBuffer.bitmap = &buffers->backBitmap;
  2292. buffers->backBitmap.pwnd = &buffers->backBitmap.wnd;
  2293. }
  2294. //
  2295. // Generic back buffers have origin of (0,0).
  2296. //
  2297. gc->backBuffer.buf.xOrigin = 0;
  2298. gc->backBuffer.buf.yOrigin = 0;
  2299. buffers->backBuffer.xOrigin = 0;
  2300. buffers->backBuffer.yOrigin = 0;
  2301. GenMcdConvertContext_exit:
  2302. if (bRet)
  2303. {
  2304. //
  2305. // Delete MCD surface.
  2306. //
  2307. if (bConvertSurface && pMcdSurfSAVE)
  2308. {
  2309. GenMcdDeleteSurface(pMcdSurfSAVE);
  2310. //
  2311. // Invalidate the shared depth buffer.
  2312. // Set depth resize routine to the generic version.
  2313. //
  2314. buffers->depthBuffer.base = 0;
  2315. buffers->depthBuffer.size = 0;
  2316. buffers->depthBuffer.outerWidth = 0;
  2317. buffers->resizeDepth = ResizeAncillaryBuffer;
  2318. //
  2319. // Since we deleted MCD surface, we get to create the generic
  2320. // buffers to replace it.
  2321. //
  2322. wglResizeBuffers(gengc, buffers->width, buffers->height);
  2323. }
  2324. else
  2325. {
  2326. //
  2327. // Didn't need to create generic buffers, but we do need to
  2328. // update the buffer info in the context.
  2329. //
  2330. wglUpdateBuffers(gengc, buffers);
  2331. }
  2332. //
  2333. // Reconnect _pMcdState; it and the MCD context resources
  2334. // will be deleted when the GLGENcontext is deleted
  2335. // (but note that pMcdState remains NULL!).
  2336. //
  2337. // We need to keep it around because we are going to continue
  2338. // to use the MCD allocated POLYARRAY buffer.
  2339. //
  2340. gengc->_pMcdState = _pMcdStateSAVE;
  2341. gengc->_pMcdState->pMcdSurf = (GENMCDSURFACE *) NULL;
  2342. gengc->_pMcdState->pDepthSpan = (__GLzValue *) NULL;
  2343. //
  2344. // Mark buffers struct so that other contexts will know that the
  2345. // MCD resources are gone.
  2346. //
  2347. buffers->flags |= GLGENBUF_MCD_LOST;
  2348. //
  2349. // Mark context as converted so we don't do it again.
  2350. //
  2351. gengc->flags |= GLGEN_MCD_CONVERTED_TO_GENERIC;
  2352. }
  2353. else
  2354. {
  2355. //
  2356. // Delete generic resources if neccessary.
  2357. //
  2358. wglDeleteScanlineBuffers(gengc);
  2359. //
  2360. // Restore the MCD information.
  2361. //
  2362. buffers->pMcdSurf = pMcdSurfSAVE;
  2363. buffers->pMcdState = buffers_pMcdStateSAVE;
  2364. gengc->pMcdState = pMcdStateSAVE;
  2365. gengc->_pMcdState = _pMcdStateSAVE;
  2366. //
  2367. // Resetting the MCD information requires that we
  2368. // reinitialization the color, depth, and pixel copy
  2369. // funcs.
  2370. //
  2371. wglInitializeColorBuffers(gengc);
  2372. wglInitializeDepthBuffer(gengc);
  2373. wglInitializePixelCopyFuncs(gengc);
  2374. if (gengc->pMcdState && gengc->pMcdState->pDepthSpan)
  2375. {
  2376. gc->depthBuffer.buf.base = gengc->pMcdState->pDepthSpan;
  2377. buffers->depthBuffer.base = gengc->pMcdState->pDepthSpan;
  2378. buffers->resizeDepth = ResizeUnownedDepthBuffer;
  2379. }
  2380. __glSetErrorEarly(gc, GL_OUT_OF_MEMORY);
  2381. }
  2382. //
  2383. // Success or failure, we've messed around with enough data to
  2384. // require revalidation.
  2385. //
  2386. (*gc->procs.applyViewport)(gc);
  2387. //!!!SP1 -- GL_INVALIDATE (which only sets the __GL_DIRTY_GENERIC bit)
  2388. //!!!SP1 should suffice now that __glGenericPickAllProcs has been
  2389. //!!!SP1 modified to repick depth procs if GL_DIRTY_GENERIC is set.
  2390. //!!!SP1 However, we are too close to ship to get good stress coverage,
  2391. //!!!SP1 so leave it as is until after NT4.0 ships.
  2392. //__GL_INVALIDATE(gc);
  2393. gc->dirtyMask |= __GL_DIRTY_ALL;
  2394. gc->validateMask |= (__GL_VALIDATE_STENCIL_FUNC |
  2395. __GL_VALIDATE_STENCIL_OP);
  2396. (*gc->procs.validate)(gc);
  2397. return bRet;
  2398. }
  2399. /******************************Public*Routine******************************\
  2400. * GenMcdCreateTexture
  2401. *
  2402. * Invoke the MCD texture creation command.
  2403. *
  2404. * Returns:
  2405. * A non-NULL MCD handle if successful, NULL otherwise.
  2406. *
  2407. * History:
  2408. * 29-April-1996 -by- Otto Berkes [ottob]
  2409. * Wrote it.
  2410. \**************************************************************************/
  2411. MCDHANDLE FASTCALL GenMcdCreateTexture(__GLGENcontext *gengc, __GLtexture *tex,
  2412. ULONG flags)
  2413. {
  2414. GENMCDSTATE *pMcdState = gengc->pMcdState;
  2415. ASSERTOPENGL(gengc->pMcdState, "GenMcdCreateTexture: null pMcdState\n");
  2416. ASSERTOPENGL(tex, "GenMcdCreateTexture: null texture pointer\n");
  2417. //
  2418. // This function can assume that MCD entry point table is already
  2419. // initialized as we cannot get here without MCD already having been
  2420. // called.
  2421. //
  2422. ASSERTOPENGL(gpMcdTable, "GenMcdCreateTexture: mcd32.dll not initialized\n");
  2423. if ((flags & MCDTEXTURE_DIRECTDRAW_SURFACES) &&
  2424. !SUPPORTS_DIRECT())
  2425. {
  2426. // Don't pass DirectDraw texture surfaces to the driver if it
  2427. // doesn't support them.
  2428. return 0;
  2429. }
  2430. return (gpMcdTable->pMCDCreateTexture)(&pMcdState->McdContext,
  2431. (MCDTEXTUREDATA *)&tex->params,
  2432. flags, NULL);
  2433. }
  2434. /******************************Public*Routine******************************\
  2435. * GenMcdDeleteTexture
  2436. *
  2437. * Invoke the MCD texture deletion command.
  2438. *
  2439. * Returns:
  2440. * TRUE if successful, FALSE otherwise.
  2441. *
  2442. * History:
  2443. * 29-April-1996 -by- Otto Berkes [ottob]
  2444. * Wrote it.
  2445. \**************************************************************************/
  2446. BOOL FASTCALL GenMcdDeleteTexture(__GLGENcontext *gengc, MCDHANDLE texHandle)
  2447. {
  2448. GENMCDSTATE *pMcdState = gengc->pMcdState;
  2449. ASSERTOPENGL(gengc->pMcdState, "GenMcdDeleteTexture: null pMcdState\n");
  2450. ASSERTOPENGL(texHandle, "GenMcdDeleteTexture: null texture handle\n");
  2451. //
  2452. // This function can assume that MCD entry point table is already
  2453. // initialized as we cannot get here without MCD already having been
  2454. // called.
  2455. //
  2456. ASSERTOPENGL(gpMcdTable, "GenMcdDeleteTexture: mcd32.dll not initialized\n");
  2457. return (BOOL)(gpMcdTable->pMCDDeleteTexture)(&pMcdState->McdContext,
  2458. (MCDHANDLE)texHandle);
  2459. }
  2460. /******************************Public*Routine******************************\
  2461. * GenMcdUpdateSubTexture
  2462. *
  2463. * Invoke the MCD subtexture update command.
  2464. *
  2465. * Returns:
  2466. * TRUE if successful, FALSE otherwise.
  2467. *
  2468. * History:
  2469. * 29-April-1996 -by- Otto Berkes [ottob]
  2470. * Wrote it.
  2471. \**************************************************************************/
  2472. BOOL FASTCALL GenMcdUpdateSubTexture(__GLGENcontext *gengc, __GLtexture *tex,
  2473. MCDHANDLE texHandle, GLint lod,
  2474. GLint xoffset, GLint yoffset,
  2475. GLsizei w, GLsizei h)
  2476. {
  2477. GENMCDSTATE *pMcdState = gengc->pMcdState;
  2478. RECTL rect;
  2479. ASSERTOPENGL(gengc->pMcdState, "GenMcdUpdateSubTexture: null pMcdState\n");
  2480. ASSERTOPENGL(texHandle, "GenMcdUpdateSubTexture: null texture handle\n");
  2481. //
  2482. // This function can assume that MCD entry point table is already
  2483. // initialized as we cannot get here without MCD already having been
  2484. // called.
  2485. //
  2486. ASSERTOPENGL(gpMcdTable, "GenMcdUpdateSubTexture: mcd32.dll not initialized\n");
  2487. rect.left = xoffset;
  2488. rect.top = yoffset;
  2489. rect.right = xoffset + w;
  2490. rect.bottom = yoffset + h;
  2491. return (BOOL)(gpMcdTable->pMCDUpdateSubTexture)(&pMcdState->McdContext,
  2492. (MCDTEXTUREDATA *)&tex->params, (MCDHANDLE)texHandle,
  2493. (ULONG)lod, &rect);
  2494. }
  2495. /******************************Public*Routine******************************\
  2496. * GenMcdUpdateTexturePalette
  2497. *
  2498. * Invoke the MCD texture palette update command.
  2499. *
  2500. * Returns:
  2501. * TRUE if successful, FALSE otherwise.
  2502. *
  2503. * History:
  2504. * 29-April-1996 -by- Otto Berkes [ottob]
  2505. * Wrote it.
  2506. \**************************************************************************/
  2507. BOOL FASTCALL GenMcdUpdateTexturePalette(__GLGENcontext *gengc, __GLtexture *tex,
  2508. MCDHANDLE texHandle, GLsizei start,
  2509. GLsizei count)
  2510. {
  2511. GENMCDSTATE *pMcdState = gengc->pMcdState;
  2512. ASSERTOPENGL(gengc->pMcdState, "GenMcdUpdateTexturePalette: null pMcdState\n");
  2513. ASSERTOPENGL(texHandle, "GenMcdUpdateTexturePalette: null texture handle\n");
  2514. //
  2515. // This function can assume that MCD entry point table is already
  2516. // initialized as we cannot get here without MCD already having been
  2517. // called.
  2518. //
  2519. ASSERTOPENGL(gpMcdTable, "GenMcdUpdateTexturePalette: mcd32.dll not initialized\n");
  2520. return (BOOL)(gpMcdTable->pMCDUpdateTexturePalette)(&pMcdState->McdContext,
  2521. (MCDTEXTUREDATA *)&tex->params, (MCDHANDLE)texHandle,
  2522. (ULONG)start, (ULONG)count);
  2523. }
  2524. /******************************Public*Routine******************************\
  2525. * GenMcdUpdateTexturePriority
  2526. *
  2527. * Invoke the MCD texture priority command.
  2528. *
  2529. * Returns:
  2530. * TRUE if successful, FALSE otherwise.
  2531. *
  2532. * History:
  2533. * 29-April-1996 -by- Otto Berkes [ottob]
  2534. * Wrote it.
  2535. \**************************************************************************/
  2536. BOOL FASTCALL GenMcdUpdateTexturePriority(__GLGENcontext *gengc, __GLtexture *tex,
  2537. MCDHANDLE texHandle)
  2538. {
  2539. GENMCDSTATE *pMcdState = gengc->pMcdState;
  2540. ASSERTOPENGL(gengc->pMcdState, "GenMcdUpdateTexturePriority: null pMcdState\n");
  2541. ASSERTOPENGL(texHandle, "GenMcdUpdateTexturePriority: null texture handle\n");
  2542. //
  2543. // This function can assume that MCD entry point table is already
  2544. // initialized as we cannot get here without MCD already having been
  2545. // called.
  2546. //
  2547. ASSERTOPENGL(gpMcdTable, "GenMcdUpdateTexturePriority: mcd32.dll not initialized\n");
  2548. return (BOOL)(gpMcdTable->pMCDUpdateTexturePriority)(&pMcdState->McdContext,
  2549. (MCDTEXTUREDATA *)&tex->params, (MCDHANDLE)texHandle);
  2550. }
  2551. /******************************Public*Routine******************************\
  2552. * GenMcdTextureStatus
  2553. *
  2554. * Invoke the MCD texture status command.
  2555. *
  2556. * Returns:
  2557. * The status for the specified texture.
  2558. *
  2559. * History:
  2560. * 29-April-1996 -by- Otto Berkes [ottob]
  2561. * Wrote it.
  2562. \**************************************************************************/
  2563. DWORD FASTCALL GenMcdTextureStatus(__GLGENcontext *gengc, MCDHANDLE texHandle)
  2564. {
  2565. GENMCDSTATE *pMcdState = gengc->pMcdState;
  2566. ASSERTOPENGL(gengc->pMcdState, "GenMcdTextureStatus: null pMcdState\n");
  2567. ASSERTOPENGL(texHandle, "GenMcdTextureStatus: null texture handle\n");
  2568. //
  2569. // This function can assume that MCD entry point table is already
  2570. // initialized as we cannot get here without MCD already having been
  2571. // called.
  2572. //
  2573. ASSERTOPENGL(gpMcdTable, "GenMcdTextureStatus: mcd32.dll not initialized\n");
  2574. return (DWORD)(gpMcdTable->pMCDTextureStatus)(&pMcdState->McdContext,
  2575. (MCDHANDLE)texHandle);
  2576. }
  2577. /******************************Public*Routine******************************\
  2578. * GenMcdUpdateTextureState
  2579. *
  2580. * Invoke the MCD texture state update command.
  2581. *
  2582. * Returns:
  2583. * TRUE if successful, FALSE otherwise.
  2584. *
  2585. * History:
  2586. * 29-April-1996 -by- Otto Berkes [ottob]
  2587. * Wrote it.
  2588. \**************************************************************************/
  2589. BOOL FASTCALL GenMcdUpdateTextureState(__GLGENcontext *gengc, __GLtexture *tex,
  2590. MCDHANDLE texHandle)
  2591. {
  2592. GENMCDSTATE *pMcdState = gengc->pMcdState;
  2593. ASSERTOPENGL(gengc->pMcdState, "GenMcdUpdateTextureState: null pMcdState\n");
  2594. ASSERTOPENGL(texHandle, "GenMcdUpdateTextureState: null texture handle\n");
  2595. //
  2596. // This function can assume that MCD entry point table is already
  2597. // initialized as we cannot get here without MCD already having been
  2598. // called.
  2599. //
  2600. ASSERTOPENGL(gpMcdTable, "GenMcdTextureStatus: mcd32.dll not initialized\n");
  2601. return (BOOL)(gpMcdTable->pMCDUpdateTextureState)(&pMcdState->McdContext,
  2602. (MCDTEXTUREDATA *)&tex->params, (MCDHANDLE)texHandle);
  2603. }
  2604. /******************************Public*Routine******************************\
  2605. * GenMcdTextureKey
  2606. *
  2607. * Invoke the MCD texture key command. Note that this call does not go to
  2608. * the display driver, but gets handled in the mcd server.
  2609. *
  2610. * Returns:
  2611. * The driver-owned key for the specified texture.
  2612. *
  2613. * History:
  2614. * 29-April-1996 -by- Otto Berkes [ottob]
  2615. * Wrote it.
  2616. \**************************************************************************/
  2617. DWORD FASTCALL GenMcdTextureKey(__GLGENcontext *gengc, MCDHANDLE texHandle)
  2618. {
  2619. GENMCDSTATE *pMcdState = gengc->pMcdState;
  2620. ASSERTOPENGL(gengc->pMcdState, "GenMcdTextureKey: null pMcdState\n");
  2621. ASSERTOPENGL(texHandle, "GenMcdTextureKey: null texture handle\n");
  2622. //
  2623. // This function can assume that MCD entry point table is already
  2624. // initialized as we cannot get here without MCD already having been
  2625. // called.
  2626. //
  2627. ASSERTOPENGL(gpMcdTable, "GenMcdTextureKey: mcd32.dll not initialized\n");
  2628. return (DWORD)(gpMcdTable->pMCDTextureKey)(&pMcdState->McdContext,
  2629. (MCDHANDLE)texHandle);
  2630. }
  2631. /******************************Public*Routine******************************\
  2632. * GenMcdDescribeLayerPlane
  2633. *
  2634. * Call the MCD driver to return information about the specified layer plane.
  2635. *
  2636. * History:
  2637. * 16-May-1996 -by- Gilman Wong [gilmanw]
  2638. * Wrote it.
  2639. \**************************************************************************/
  2640. BOOL FASTCALL GenMcdDescribeLayerPlane(HDC hdc, int iPixelFormat,
  2641. int iLayerPlane, UINT nBytes,
  2642. LPLAYERPLANEDESCRIPTOR plpd)
  2643. {
  2644. BOOL bRet = FALSE;
  2645. //
  2646. // Cannot assume that MCD is intialized.
  2647. //
  2648. if (gpMcdTable || bInitMcd(hdc))
  2649. {
  2650. //
  2651. // Caller (wglDescribeLayerPlane in client\layer.c) validates
  2652. // size.
  2653. //
  2654. ASSERTOPENGL(nBytes >= sizeof(LAYERPLANEDESCRIPTOR),
  2655. "GenMcdDescribeLayerPlane: bad size\n");
  2656. bRet = (gpMcdTable->pMCDDescribeLayerPlane)(hdc, iPixelFormat,
  2657. iLayerPlane, plpd);
  2658. }
  2659. return bRet;
  2660. }
  2661. /******************************Public*Routine******************************\
  2662. * GenMcdSetLayerPaletteEntries
  2663. *
  2664. * Set the logical palette for the specified layer plane.
  2665. *
  2666. * The logical palette is cached in the GLGENwindow structure and is flushed
  2667. * to the driver when GenMcdRealizeLayerPalette is called.
  2668. *
  2669. * History:
  2670. * 16-May-1996 -by- Gilman Wong [gilmanw]
  2671. * Wrote it.
  2672. \**************************************************************************/
  2673. int FASTCALL GenMcdSetLayerPaletteEntries(HDC hdc, int iLayerPlane,
  2674. int iStart, int cEntries,
  2675. CONST COLORREF *pcr)
  2676. {
  2677. int iRet = 0;
  2678. GLGENwindow *pwnd;
  2679. GLWINDOWID gwid;
  2680. if (!pcr)
  2681. return iRet;
  2682. //
  2683. // Need to find the window that has the layer palettes.
  2684. //
  2685. WindowIdFromHdc(hdc, &gwid);
  2686. pwnd = pwndGetFromID(&gwid);
  2687. if (pwnd)
  2688. {
  2689. GLGENlayerInfo *plyri;
  2690. ENTER_WINCRIT(pwnd);
  2691. //
  2692. // Get the layer plane information.
  2693. //
  2694. plyri = plyriGet(pwnd, hdc, iLayerPlane);
  2695. if (plyri)
  2696. {
  2697. //
  2698. // Set the palette information in the layer plane structure.
  2699. //
  2700. iRet = min(plyri->cPalEntries - iStart, cEntries);
  2701. memcpy(&plyri->pPalEntries[iStart], pcr, iRet * sizeof(COLORREF));
  2702. }
  2703. pwndUnlock(pwnd, NULL);
  2704. }
  2705. return iRet;
  2706. }
  2707. /******************************Public*Routine******************************\
  2708. * GenMcdGetLayerPaletteEntries
  2709. *
  2710. * Get the logical palette from the specified layer plane.
  2711. *
  2712. * The logical palette is cached in the GLGENwindow structure and is flushed
  2713. * to the driver when GenMcdRealizeLayerPalette is called.
  2714. *
  2715. * History:
  2716. * 16-May-1996 -by- Gilman Wong [gilmanw]
  2717. * Wrote it.
  2718. \**************************************************************************/
  2719. int FASTCALL GenMcdGetLayerPaletteEntries(HDC hdc, int iLayerPlane,
  2720. int iStart, int cEntries,
  2721. COLORREF *pcr)
  2722. {
  2723. int iRet = 0;
  2724. GLGENwindow *pwnd;
  2725. GLWINDOWID gwid;
  2726. if (!pcr)
  2727. return iRet;
  2728. //
  2729. // Need to find the window.
  2730. //
  2731. WindowIdFromHdc(hdc, &gwid);
  2732. pwnd = pwndGetFromID(&gwid);
  2733. if (pwnd)
  2734. {
  2735. GLGENlayerInfo *plyri;
  2736. ENTER_WINCRIT(pwnd);
  2737. //
  2738. // Get the layer plane information.
  2739. //
  2740. plyri = plyriGet(pwnd, hdc, iLayerPlane);
  2741. if (plyri)
  2742. {
  2743. //
  2744. // Get the palette information from the layer plane structure.
  2745. //
  2746. iRet = min(plyri->cPalEntries - iStart, cEntries);
  2747. memcpy(pcr, &plyri->pPalEntries[iStart], iRet * sizeof(COLORREF));
  2748. }
  2749. pwndUnlock(pwnd, NULL);
  2750. }
  2751. return iRet;
  2752. }
  2753. /******************************Public*Routine******************************\
  2754. * GenMcdRealizeLayerPalette
  2755. *
  2756. * Send the logical palette of the specified layer plane to the MCD driver.
  2757. * If the bRealize flag is TRUE, the palette is mapped into the physical
  2758. * palette of the specified layer plane. Otherwise, this is a signal to the
  2759. * driver that the physical palette is no longer needed.
  2760. *
  2761. * History:
  2762. * 16-May-1996 -by- Gilman Wong [gilmanw]
  2763. * Wrote it.
  2764. \**************************************************************************/
  2765. int FASTCALL GenMcdRealizeLayerPalette(HDC hdc, int iLayerPlane,
  2766. BOOL bRealize)
  2767. {
  2768. int iRet = 0;
  2769. GLWINDOWID gwid;
  2770. //
  2771. // Cannot assume that MCD is intialized.
  2772. //
  2773. if (gpMcdTable || bInitMcd(hdc))
  2774. {
  2775. GLGENwindow *pwnd;
  2776. //
  2777. // Need to find the window.
  2778. //
  2779. WindowIdFromHdc(hdc, &gwid);
  2780. pwnd = pwndGetFromID(&gwid);
  2781. if (pwnd)
  2782. {
  2783. GLGENlayerInfo *plyri;
  2784. ENTER_WINCRIT(pwnd);
  2785. //
  2786. // Get the layer plane information.
  2787. //
  2788. plyri = plyriGet(pwnd, hdc, iLayerPlane);
  2789. if (plyri)
  2790. {
  2791. //
  2792. // Set the palette from the logical palette stored
  2793. // in the layer plane structure.
  2794. //
  2795. iRet = (gpMcdTable->pMCDSetLayerPalette)
  2796. (hdc, iLayerPlane, bRealize,
  2797. plyri->cPalEntries,
  2798. &plyri->pPalEntries[0]);
  2799. }
  2800. pwndUnlock(pwnd, NULL);
  2801. }
  2802. }
  2803. return iRet;
  2804. }
  2805. /******************************Public*Routine******************************\
  2806. * GenMcdSwapLayerBuffers
  2807. *
  2808. * Swap the individual layer planes specified in fuFlags.
  2809. *
  2810. * History:
  2811. * 16-May-1996 -by- Gilman Wong [gilmanw]
  2812. * Wrote it.
  2813. \**************************************************************************/
  2814. BOOL FASTCALL GenMcdSwapLayerBuffers(HDC hdc, UINT fuFlags)
  2815. {
  2816. BOOL bRet = FALSE;
  2817. GLGENwindow *pwnd;
  2818. GLWINDOWID gwid;
  2819. //
  2820. // Need the window.
  2821. //
  2822. WindowIdFromHdc(hdc, &gwid);
  2823. pwnd = pwndGetFromID(&gwid);
  2824. if (pwnd)
  2825. {
  2826. MCDCONTEXT McdContextTmp;
  2827. ENTER_WINCRIT(pwnd);
  2828. //
  2829. // From the window, we can get the buffers struct.
  2830. //
  2831. if (pwnd->buffers != NULL)
  2832. {
  2833. __GLGENbuffers *buffers = pwnd->buffers;
  2834. //
  2835. // Call MCDSwap if we can (MCD context is required).
  2836. //
  2837. if (buffers->pMcdSurf)
  2838. {
  2839. ASSERTOPENGL(gpMcdTable,
  2840. "GenMcdSwapLayerBuffers: "
  2841. "mcd32.dll not initialized\n");
  2842. McdContextTmp.hdc = hdc;
  2843. bRet = (gpMcdTable->pMCDSwap)(&McdContextTmp, fuFlags);
  2844. }
  2845. }
  2846. //
  2847. // Release the window.
  2848. //
  2849. pwndUnlock(pwnd, NULL);
  2850. }
  2851. return bRet;
  2852. }
  2853. /******************************Public*Routine******************************\
  2854. * GenMcdUpdatePixelState
  2855. *
  2856. * Update MCD pixel state from the OpenGL state.
  2857. *
  2858. * This call only adds a state structure to the current state command.
  2859. * It is assumed that the caller has already called MCDBeginState and
  2860. * will call MCDFlushState.
  2861. *
  2862. * Note: pixel maps (glPixelMap) are not updated by this function. Because
  2863. * they are not used often, they are delayed but rather flushed to the driver
  2864. * immediately.
  2865. *
  2866. * History:
  2867. * 27-May-1996 -by- Gilman Wong [gilmanw]
  2868. * Wrote it.
  2869. \**************************************************************************/
  2870. void FASTCALL GenMcdUpdatePixelState(__GLGENcontext *gengc)
  2871. {
  2872. __GLcontext *gc = &gengc->gc;
  2873. GENMCDSTATE *pMcdState = gengc->pMcdState;
  2874. MCDPIXELSTATE McdPixelState;
  2875. ASSERTOPENGL(gengc->pMcdState, "GenMcdUpdatePixelState: null pMcdState\n");
  2876. //
  2877. // This function can assume that MCD entry point table is already
  2878. // initialized as we cannot get here without MCD already having been
  2879. // called.
  2880. //
  2881. ASSERTOPENGL(gpMcdTable, "GenMcdUpdatePixelState: mcd32.dll not initialized\n");
  2882. //
  2883. // Compute MCD pixel state from the current OpenGL context state.
  2884. //
  2885. //
  2886. // Pixel transfer modes.
  2887. //
  2888. // MCDPIXELTRANSFER and __GLpixelTransferMode structures are the same.
  2889. //
  2890. McdPixelState.pixelTransferModes
  2891. = *((MCDPIXELTRANSFER *) &gengc->gc.state.pixel.transferMode);
  2892. //
  2893. // Pixel pack modes.
  2894. //
  2895. // MCDPIXELPACK and __GLpixelPackMode structures are the same.
  2896. //
  2897. McdPixelState.pixelPackModes
  2898. = *((MCDPIXELPACK *) &gengc->gc.state.pixel.packModes);
  2899. //
  2900. // Pixel unpack modes.
  2901. //
  2902. // MCDPIXELUNPACK and __GLpixelUnpackMode structures are the same.
  2903. //
  2904. McdPixelState.pixelUnpackModes
  2905. = *((MCDPIXELUNPACK *) &gengc->gc.state.pixel.unpackModes);
  2906. //
  2907. // Read buffer.
  2908. //
  2909. McdPixelState.readBuffer = gengc->gc.state.pixel.readBuffer;
  2910. //
  2911. // Current raster position.
  2912. //
  2913. McdPixelState.rasterPos = *((MCDCOORD *) &gengc->gc.state.current.rasterPos.window);
  2914. //
  2915. // Send MCDPIXELSTATE to the state cmd.
  2916. //
  2917. (gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  2918. MCD_PIXEL_STATE,
  2919. &McdPixelState,
  2920. sizeof(McdPixelState));
  2921. }
  2922. /******************************Public*Routine******************************\
  2923. * GenMcdUpdateFineState
  2924. *
  2925. * Update fine-grained MCD state from the OpenGL state.
  2926. *
  2927. * This call only adds state structures to the current state command.
  2928. * It is assumed that the caller has already called MCDBeginState and
  2929. * will call MCDFlushState.
  2930. *
  2931. * History:
  2932. * 13-Mar-1997 -by- Drew Bliss [drewb]
  2933. * Created.
  2934. \**************************************************************************/
  2935. void FASTCALL GenMcdUpdateFineState(__GLGENcontext *gengc)
  2936. {
  2937. __GLcontext *gc = &gengc->gc;
  2938. GENMCDSTATE *pMcdState = gengc->pMcdState;
  2939. MCDPIXELSTATE McdPixelState;
  2940. ASSERTOPENGL(pMcdState, "GenMcdUpdateFineState: null pMcdState\n");
  2941. //
  2942. // This function can assume that MCD entry point table is already
  2943. // initialized as we cannot get here without MCD already having been
  2944. // called.
  2945. //
  2946. ASSERTOPENGL(gpMcdTable, "GenMcdUpdateFineState: "
  2947. "mcd32.dll not initialized\n");
  2948. //
  2949. // Compute MCD state from the current OpenGL context state.
  2950. //
  2951. if (MCD_STATE_DIRTYTEST(gengc, ENABLES))
  2952. {
  2953. MCDENABLESTATE state;
  2954. state.enables = gc->state.enables.general;
  2955. (gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  2956. MCD_ENABLE_STATE,
  2957. &state, sizeof(state));
  2958. }
  2959. if (MCD_STATE_DIRTYTEST(gengc, TEXTURE))
  2960. {
  2961. MCDTEXTUREENABLESTATE state;
  2962. state.textureEnabled = gc->texture.textureEnabled;
  2963. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  2964. MCD_TEXTURE_ENABLE_STATE,
  2965. &state, sizeof(state));
  2966. }
  2967. if (MCD_STATE_DIRTYTEST(gengc, FOG))
  2968. {
  2969. MCDFOGSTATE state;
  2970. *((__GLcolor *) &state.fogColor) = gc->state.fog.color;
  2971. state.fogIndex = gc->state.fog.index;
  2972. state.fogDensity = gc->state.fog.density;
  2973. state.fogStart = gc->state.fog.start;
  2974. state.fogEnd = gc->state.fog.end;
  2975. state.fogMode = gc->state.fog.mode;
  2976. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  2977. MCD_FOG_STATE,
  2978. &state, sizeof(state));
  2979. }
  2980. if (MCD_STATE_DIRTYTEST(gengc, SHADEMODEL))
  2981. {
  2982. MCDSHADEMODELSTATE state;
  2983. state.shadeModel = gc->state.light.shadingModel;
  2984. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  2985. MCD_SHADEMODEL_STATE,
  2986. &state, sizeof(state));
  2987. }
  2988. if (MCD_STATE_DIRTYTEST(gengc, POINTDRAW))
  2989. {
  2990. MCDPOINTDRAWSTATE state;
  2991. state.pointSize = gc->state.point.requestedSize;
  2992. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  2993. MCD_POINTDRAW_STATE,
  2994. &state, sizeof(state));
  2995. }
  2996. if (MCD_STATE_DIRTYTEST(gengc, LINEDRAW))
  2997. {
  2998. MCDLINEDRAWSTATE state;
  2999. state.lineWidth = gc->state.line.requestedWidth;
  3000. state.lineStipplePattern = gc->state.line.stipple;
  3001. state.lineStippleRepeat = gc->state.line.stippleRepeat;
  3002. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3003. MCD_LINEDRAW_STATE,
  3004. &state, sizeof(state));
  3005. }
  3006. if (MCD_STATE_DIRTYTEST(gengc, POLYDRAW))
  3007. {
  3008. MCDPOLYDRAWSTATE state;
  3009. state.cullFaceMode = gc->state.polygon.cull;
  3010. state.frontFace = gc->state.polygon.frontFaceDirection;
  3011. state.polygonModeFront = gc->state.polygon.frontMode;
  3012. state.polygonModeBack = gc->state.polygon.backMode;
  3013. memcpy(&state.polygonStipple, &gc->state.polygonStipple.stipple,
  3014. sizeof(state.polygonStipple));
  3015. state.zOffsetFactor = gc->state.polygon.factor;
  3016. state.zOffsetUnits = gc->state.polygon.units;
  3017. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3018. MCD_POLYDRAW_STATE,
  3019. &state, sizeof(state));
  3020. }
  3021. if (MCD_STATE_DIRTYTEST(gengc, ALPHATEST))
  3022. {
  3023. MCDALPHATESTSTATE state;
  3024. state.alphaTestFunc = gc->state.raster.alphaFunction;
  3025. state.alphaTestRef = gc->state.raster.alphaReference;
  3026. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3027. MCD_ALPHATEST_STATE,
  3028. &state, sizeof(state));
  3029. }
  3030. if (MCD_STATE_DIRTYTEST(gengc, DEPTHTEST))
  3031. {
  3032. MCDDEPTHTESTSTATE state;
  3033. state.depthTestFunc = gc->state.depth.testFunc;
  3034. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3035. MCD_DEPTHTEST_STATE,
  3036. &state, sizeof(state));
  3037. }
  3038. if (MCD_STATE_DIRTYTEST(gengc, BLEND))
  3039. {
  3040. MCDBLENDSTATE state;
  3041. state.blendSrc = gc->state.raster.blendSrc;
  3042. state.blendDst = gc->state.raster.blendDst;
  3043. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3044. MCD_BLEND_STATE,
  3045. &state, sizeof(state));
  3046. }
  3047. if (MCD_STATE_DIRTYTEST(gengc, LOGICOP))
  3048. {
  3049. MCDLOGICOPSTATE state;
  3050. state.logicOpMode = gc->state.raster.logicOp;
  3051. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3052. MCD_LOGICOP_STATE,
  3053. &state, sizeof(state));
  3054. }
  3055. if (MCD_STATE_DIRTYTEST(gengc, FBUFCTRL))
  3056. {
  3057. MCDFRAMEBUFSTATE state;
  3058. state.drawBuffer = gc->state.raster.drawBuffer;
  3059. state.indexWritemask = gc->state.raster.writeMask;
  3060. state.colorWritemask[0] = gc->state.raster.rMask;
  3061. state.colorWritemask[1] = gc->state.raster.gMask;
  3062. state.colorWritemask[2] = gc->state.raster.bMask;
  3063. state.colorWritemask[3] = gc->state.raster.aMask;
  3064. state.depthWritemask = gc->state.depth.writeEnable;
  3065. // To be consistent, we will scale the clear color to whatever
  3066. // the MCD driver specified:
  3067. state.colorClearValue.r =
  3068. gc->state.raster.clear.r * gc->redVertexScale;
  3069. state.colorClearValue.g =
  3070. gc->state.raster.clear.g * gc->greenVertexScale;
  3071. state.colorClearValue.b =
  3072. gc->state.raster.clear.b * gc->blueVertexScale;
  3073. state.colorClearValue.a =
  3074. gc->state.raster.clear.a * gc->alphaVertexScale;
  3075. state.indexClearValue = gc->state.raster.clearIndex;
  3076. state.stencilClearValue = (USHORT) gc->state.stencil.clear;
  3077. state.depthClearValue = (MCDDOUBLE) (gc->state.depth.clear *
  3078. gengc->genAccel.zDevScale);
  3079. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3080. MCD_FRAMEBUF_STATE,
  3081. &state, sizeof(state));
  3082. }
  3083. if (MCD_STATE_DIRTYTEST(gengc, LIGHTMODEL))
  3084. {
  3085. MCDLIGHTMODELSTATE state;
  3086. *((__GLcolor *)&state.ambient) = gc->state.light.model.ambient;
  3087. state.localViewer = gc->state.light.model.localViewer;
  3088. state.twoSided = gc->state.light.model.twoSided;
  3089. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3090. MCD_LIGHT_MODEL_STATE,
  3091. &state, sizeof(state));
  3092. }
  3093. if (MCD_STATE_DIRTYTEST(gengc, HINTS))
  3094. {
  3095. MCDHINTSTATE state;
  3096. state.perspectiveCorrectionHint =
  3097. gc->state.hints.perspectiveCorrection;
  3098. state.pointSmoothHint = gc->state.hints.pointSmooth;
  3099. state.lineSmoothHint = gc->state.hints.lineSmooth;
  3100. state.polygonSmoothHint = gc->state.hints.polygonSmooth;
  3101. state.fogHint = gc->state.hints.fog;
  3102. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3103. MCD_HINT_STATE,
  3104. &state, sizeof(state));
  3105. }
  3106. if (MCD_STATE_DIRTYTEST(gengc, CLIPCTRL))
  3107. {
  3108. MCDCLIPSTATE state;
  3109. ULONG i, mask, numClipPlanes;
  3110. memset(state.userClipPlanes, 0, sizeof(state.userClipPlanes));
  3111. memset(state.userClipPlanesInv, 0, sizeof(state.userClipPlanesInv));
  3112. //
  3113. // Number of user defined clip planes should match. However,
  3114. // rather than assume this, let's take the min and be robust.
  3115. //
  3116. ASSERTOPENGL(sizeof(__GLcoord) == sizeof(MCDCOORD),
  3117. "GenMcdUpdateFineState: coord struct mismatch\n");
  3118. ASSERTOPENGL(MCD_MAX_USER_CLIP_PLANES ==
  3119. gc->constants.numberOfClipPlanes,
  3120. "GenMcdUpdateFineState: num clip planes mismatch\n");
  3121. numClipPlanes = min(MCD_MAX_USER_CLIP_PLANES,
  3122. gc->constants.numberOfClipPlanes);
  3123. state.userClipEnables = gc->state.enables.clipPlanes;
  3124. for (i = 0, mask = 1; i < numClipPlanes; i++, mask <<= 1)
  3125. {
  3126. if (mask & gc->state.enables.clipPlanes)
  3127. {
  3128. state.userClipPlanes[i] =
  3129. *(MCDCOORD *)&gc->state.transform.eyeClipPlanesSet[i];
  3130. state.userClipPlanesInv[i] =
  3131. *(MCDCOORD *)&gc->state.transform.eyeClipPlanes[i];
  3132. }
  3133. }
  3134. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3135. MCD_CLIP_STATE,
  3136. &state, sizeof(state));
  3137. }
  3138. if (MCD_STATE_DIRTYTEST(gengc, STENCILTEST))
  3139. {
  3140. MCDSTENCILTESTSTATE state;
  3141. state.stencilTestFunc = gc->state.stencil.testFunc;
  3142. state.stencilMask = (USHORT) gc->state.stencil.mask;
  3143. state.stencilRef = (USHORT) gc->state.stencil.reference;
  3144. state.stencilFail = gc->state.stencil.fail;
  3145. state.stencilDepthFail = gc->state.stencil.depthFail;
  3146. state.stencilDepthPass = gc->state.stencil.depthPass;
  3147. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3148. MCD_STENCILTEST_STATE,
  3149. &state, sizeof(state));
  3150. }
  3151. //
  3152. // The rest of the state is only interesting to a 2.0 driver,
  3153. // so only send it to a 2.0 driver.
  3154. //
  3155. if (!SUPPORTS_20())
  3156. {
  3157. return;
  3158. }
  3159. if (MCD_STATE_DIRTYTEST(gengc, TEXTRANSFORM))
  3160. {
  3161. MCDTEXTURETRANSFORMSTATE state;
  3162. ASSERTOPENGL(sizeof(gc->transform.texture->matrix) ==
  3163. sizeof(MCDMATRIX),
  3164. "Matrix size mismatch\n");
  3165. memcpy(&state.transform, &gc->transform.texture->matrix,
  3166. sizeof(state.transform));
  3167. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3168. MCD_TEXTURE_TRANSFORM_STATE,
  3169. &state, sizeof(state));
  3170. }
  3171. if (MCD_STATE_DIRTYTEST(gengc, TEXGEN))
  3172. {
  3173. MCDTEXTUREGENERATIONSTATE state;
  3174. ASSERTOPENGL(sizeof(__GLtextureCoordState) ==
  3175. sizeof(MCDTEXTURECOORDGENERATION),
  3176. "MCDTEXTURECOORDGENERATION mismatch\n");
  3177. *(__GLtextureCoordState *)&state.s = gc->state.texture.s;
  3178. *(__GLtextureCoordState *)&state.t = gc->state.texture.t;
  3179. *(__GLtextureCoordState *)&state.r = gc->state.texture.r;
  3180. *(__GLtextureCoordState *)&state.q = gc->state.texture.q;
  3181. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3182. MCD_TEXTURE_GENERATION_STATE,
  3183. &state, sizeof(state));
  3184. }
  3185. if (MCD_STATE_DIRTYTEST(gengc, MATERIAL))
  3186. {
  3187. MCDMATERIALSTATE state;
  3188. ASSERTOPENGL(sizeof(MCDMATERIAL) == sizeof(__GLmaterialState),
  3189. "Material size mismatch\n");
  3190. *(__GLmaterialState *)&state.materials[MCDVERTEX_FRONTFACE] =
  3191. gc->state.light.front;
  3192. *(__GLmaterialState *)&state.materials[MCDVERTEX_BACKFACE] =
  3193. gc->state.light.back;
  3194. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3195. MCD_MATERIAL_STATE,
  3196. &state, sizeof(state));
  3197. }
  3198. if (MCD_STATE_DIRTYTEST(gengc, LIGHTS))
  3199. {
  3200. // Extra light is to hold the MCDLIGHTSTATE
  3201. MCDLIGHT lights[MCD_MAX_LIGHTS+1];
  3202. MCDLIGHT *light;
  3203. MCDLIGHTSOURCESTATE *state;
  3204. __GLlightSourceState *lss;
  3205. ULONG bit;
  3206. ASSERTOPENGL(sizeof(MCDLIGHTSOURCESTATE) <= sizeof(MCDLIGHT),
  3207. "MCDLIGHTSTATE too large\n");
  3208. ASSERTOPENGL(gc->constants.numberOfLights <= MCD_MAX_LIGHTS,
  3209. "Too many lights\n");
  3210. ASSERTOPENGL(sizeof(__GLlightSourceState) >= sizeof(MCDLIGHT),
  3211. "__GLlightSourceState too small\n");
  3212. // We attempt to optimize this state request by only
  3213. // sending down the lights that have changed.
  3214. light = &lights[1];
  3215. state = (MCDLIGHTSOURCESTATE *)
  3216. ((BYTE *)light - sizeof(MCDLIGHTSOURCESTATE));
  3217. state->enables = gc->state.enables.lights;
  3218. state->changed = gc->state.light.dirtyLights;
  3219. gc->state.light.dirtyLights = 0;
  3220. bit = 1;
  3221. lss = gc->state.light.source;
  3222. while (bit < (1UL << gc->constants.numberOfLights))
  3223. {
  3224. if (state->changed & bit)
  3225. {
  3226. // MCDLIGHT is a subset of __GLlightSourceState.
  3227. memcpy(light, lss, sizeof(MCDLIGHT));
  3228. light++;
  3229. }
  3230. bit <<= 1;
  3231. lss++;
  3232. }
  3233. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3234. MCD_LIGHT_SOURCE_STATE,
  3235. state, (ULONG)((BYTE *)light-(BYTE *)state));
  3236. }
  3237. if (MCD_STATE_DIRTYTEST(gengc, COLORMATERIAL))
  3238. {
  3239. MCDCOLORMATERIALSTATE state;
  3240. state.face = gc->state.light.colorMaterialFace;
  3241. state.mode = gc->state.light.colorMaterialParam;
  3242. (*gpMcdTable->pMCDAddStateStruct)(pMcdState->McdCmdBatch.pv,
  3243. MCD_COLOR_MATERIAL_STATE,
  3244. &state, sizeof(state));
  3245. }
  3246. }
  3247. /******************************Public*Routine******************************\
  3248. * GenMcdDrawPix
  3249. *
  3250. * Stub to call MCDDrawPixels.
  3251. *
  3252. * History:
  3253. * 27-May-1996 -by- Gilman Wong [gilmanw]
  3254. * Wrote it.
  3255. \**************************************************************************/
  3256. ULONG FASTCALL GenMcdDrawPix(__GLGENcontext *gengc, ULONG width,
  3257. ULONG height, ULONG format, ULONG type,
  3258. VOID *pPixels, BOOL packed)
  3259. {
  3260. GENMCDSTATE *pMcdState = gengc->pMcdState;
  3261. ASSERTOPENGL(gengc->pMcdState, "GenMcdDrawPix: null pMcdState\n");
  3262. //
  3263. // This function can assume that MCD entry point table is already
  3264. // initialized as we cannot get here without MCD already having been
  3265. // called.
  3266. //
  3267. ASSERTOPENGL(gpMcdTable, "GenMcdDrawPix: mcd32.dll not initialized\n");
  3268. //
  3269. // Before calling MCD to draw, flush state.
  3270. //
  3271. vFlushDirtyState(gengc);
  3272. return (gpMcdTable->pMCDDrawPixels)(&gengc->pMcdState->McdContext,
  3273. width, height, format, type,
  3274. pPixels, packed);
  3275. }
  3276. /******************************Public*Routine******************************\
  3277. * GenMcdReadPix
  3278. *
  3279. * Stub to call MCDReadPixels.
  3280. *
  3281. * History:
  3282. * 27-May-1996 -by- Gilman Wong [gilmanw]
  3283. * Wrote it.
  3284. \**************************************************************************/
  3285. ULONG FASTCALL GenMcdReadPix(__GLGENcontext *gengc, LONG x, LONG y,
  3286. ULONG width, ULONG height, ULONG format,
  3287. ULONG type, VOID *pPixels)
  3288. {
  3289. GENMCDSTATE *pMcdState = gengc->pMcdState;
  3290. ASSERTOPENGL(gengc->pMcdState, "GenMcdReadPix: null pMcdState\n");
  3291. //
  3292. // This function can assume that MCD entry point table is already
  3293. // initialized as we cannot get here without MCD already having been
  3294. // called.
  3295. //
  3296. ASSERTOPENGL(gpMcdTable, "GenMcdReadPix: mcd32.dll not initialized\n");
  3297. //
  3298. // Before calling MCD to draw, flush state.
  3299. //
  3300. vFlushDirtyState(gengc);
  3301. return (gpMcdTable->pMCDReadPixels)(&gengc->pMcdState->McdContext,
  3302. x, y, width, height, format, type,
  3303. pPixels);
  3304. }
  3305. /******************************Public*Routine******************************\
  3306. * GenMcdCopyPix
  3307. *
  3308. * Stub to call MCDCopyPixels.
  3309. *
  3310. * History:
  3311. * 27-May-1996 -by- Gilman Wong [gilmanw]
  3312. * Wrote it.
  3313. \**************************************************************************/
  3314. ULONG FASTCALL GenMcdCopyPix(__GLGENcontext *gengc, LONG x, LONG y,
  3315. ULONG width, ULONG height, ULONG type)
  3316. {
  3317. GENMCDSTATE *pMcdState = gengc->pMcdState;
  3318. ASSERTOPENGL(gengc->pMcdState, "GenMcdCopyPix: null pMcdState\n");
  3319. //
  3320. // This function can assume that MCD entry point table is already
  3321. // initialized as we cannot get here without MCD already having been
  3322. // called.
  3323. //
  3324. ASSERTOPENGL(gpMcdTable, "GenMcdCopyPix: mcd32.dll not initialized\n");
  3325. //
  3326. // Before calling MCD to draw, flush state.
  3327. //
  3328. vFlushDirtyState(gengc);
  3329. return (gpMcdTable->pMCDCopyPixels)(&gengc->pMcdState->McdContext,
  3330. x, y, width, height, type);
  3331. }
  3332. /******************************Public*Routine******************************\
  3333. * GenMcdPixelMap
  3334. *
  3335. * Stub to call MCDPixelMap.
  3336. *
  3337. * History:
  3338. * 27-May-1996 -by- Gilman Wong [gilmanw]
  3339. * Wrote it.
  3340. \**************************************************************************/
  3341. ULONG FASTCALL GenMcdPixelMap(__GLGENcontext *gengc, ULONG mapType,
  3342. ULONG mapSize, VOID *pMap)
  3343. {
  3344. GENMCDSTATE *pMcdState = gengc->pMcdState;
  3345. ASSERTOPENGL(gengc->pMcdState, "GenMcdPixelMap: null pMcdState\n");
  3346. //
  3347. // This function can assume that MCD entry point table is already
  3348. // initialized as we cannot get here without MCD already having been
  3349. // called.
  3350. //
  3351. ASSERTOPENGL(gpMcdTable, "GenMcdPixelMap: mcd32.dll not initialized\n");
  3352. return (gpMcdTable->pMCDPixelMap)(&gengc->pMcdState->McdContext,
  3353. mapType, mapSize, pMap);
  3354. }
  3355. /******************************Public*Routine******************************\
  3356. *
  3357. * GenMcdDestroyWindow
  3358. *
  3359. * Passes on GLGENwindow cleanup notifications
  3360. *
  3361. * History:
  3362. * Thu Sep 19 12:01:40 1996 -by- Drew Bliss [drewb]
  3363. * Created
  3364. *
  3365. \**************************************************************************/
  3366. void FASTCALL GenMcdDestroyWindow(GLGENwindow *pwnd)
  3367. {
  3368. HDC hdc;
  3369. //
  3370. // This function can assume that MCD entry point table is already
  3371. // initialized as we cannot get here without MCD already having been
  3372. // called.
  3373. //
  3374. ASSERTOPENGL(gpMcdTable, "GenMcdDestroyWindow: "
  3375. "mcd32.dll not initialized\n");
  3376. // The HDC stored in the pwnd may no longer be valid, so if there's
  3377. // a window associated with the pwnd get a fresh DC.
  3378. if (pwnd->gwid.iType == GLWID_DDRAW ||
  3379. pwnd->gwid.hwnd == NULL)
  3380. {
  3381. hdc = pwnd->gwid.hdc;
  3382. }
  3383. else
  3384. {
  3385. hdc = GetDC(pwnd->gwid.hwnd);
  3386. if (hdc == NULL)
  3387. {
  3388. WARNING("GenMcdDestroyWindow unable to GetDC\n");
  3389. return;
  3390. }
  3391. }
  3392. (gpMcdTable->pMCDDestroyWindow)(hdc, pwnd->dwMcdWindow);
  3393. if (pwnd->gwid.iType != GLWID_DDRAW &&
  3394. pwnd->gwid.hwnd != NULL)
  3395. {
  3396. ReleaseDC(pwnd->gwid.hwnd, hdc);
  3397. }
  3398. }
  3399. /******************************Public*Routine******************************\
  3400. *
  3401. * GenMcdGetTextureFormats
  3402. *
  3403. * History:
  3404. * Thu Sep 26 18:34:49 1996 -by- Drew Bliss [drewb]
  3405. * Created
  3406. *
  3407. \**************************************************************************/
  3408. int FASTCALL GenMcdGetTextureFormats(__GLGENcontext *gengc, int nFmts,
  3409. struct _DDSURFACEDESC *pddsd)
  3410. {
  3411. GENMCDSTATE *pMcdState = gengc->pMcdState;
  3412. ASSERTOPENGL(gengc->pMcdState,
  3413. "GenMcdGetMcdTextureFormats: null pMcdState\n");
  3414. //
  3415. // This function can assume that MCD entry point table is already
  3416. // initialized as we cannot get here without MCD already having been
  3417. // called.
  3418. //
  3419. ASSERTOPENGL(gpMcdTable,
  3420. "GenMcdGetMcdTextureFormats: mcd32.dll not initialized\n");
  3421. return (gpMcdTable->pMCDGetTextureFormats)(&gengc->pMcdState->McdContext,
  3422. nFmts, pddsd);
  3423. }
  3424. /******************************Public*Routine******************************\
  3425. *
  3426. * GenMcdSwapMultiple
  3427. *
  3428. * History:
  3429. * Tue Oct 15 12:51:09 1996 -by- Drew Bliss [drewb]
  3430. * Created
  3431. *
  3432. \**************************************************************************/
  3433. DWORD FASTCALL GenMcdSwapMultiple(UINT cBuffers, GENMCDSWAP *pgms)
  3434. {
  3435. //
  3436. // This function can assume that MCD entry point table is already
  3437. // initialized as we cannot get here without MCD already having been
  3438. // called.
  3439. //
  3440. ASSERTOPENGL(gpMcdTable, "GenMcdSwapMultiple: "
  3441. "mcd32.dll not initialized\n");
  3442. return (gpMcdTable->pMCDSwapMultiple)(pgms[0].pwswap->hdc, cBuffers, pgms);
  3443. }
  3444. /******************************Public*Routine******************************\
  3445. * GenMcdProcessPrim
  3446. *
  3447. * Process the primitives in the POLYARRAY/POLYDATA array pointed to by pa.
  3448. * The primitives are chained together as a linked list terminated by a
  3449. * NULL. The return value is a pointer to the first unhandled primitive
  3450. * (NULL if the entire chain is successfully processed).
  3451. *
  3452. * This routine differs from GenMcdProcessPrim in that it is the MCD 2.0
  3453. * entry point for front-end processors and so calls MCDrvProcess rather
  3454. * than MCDrvDraw.
  3455. *
  3456. * Returns:
  3457. * NULL if entire batch is processed; otherwise, return value is a pointer
  3458. * to the unhandled portion of the chain.
  3459. *
  3460. * History:
  3461. * 13-Mar-1997 -by- Drew Bliss [drewb]
  3462. * Created from GenMcdDrawPrim.
  3463. \**************************************************************************/
  3464. POLYARRAY * FASTCALL GenMcdProcessPrim(__GLGENcontext *gengc, POLYARRAY *pa,
  3465. ULONG cmdFlagsAll, ULONG primFlags,
  3466. MCDTRANSFORM *pMCDTransform,
  3467. MCDMATERIALCHANGES *pMCDMatChanges)
  3468. {
  3469. GENMCDSTATE *pMcdState = gengc->pMcdState;
  3470. int levels;
  3471. LPDIRECTDRAWSURFACE *pdds;
  3472. if (!SUPPORTS_20())
  3473. {
  3474. return pa;
  3475. }
  3476. ASSERTOPENGL(gengc->pMcdState, "GenMcdProcessPrim: null pMcdState\n");
  3477. //
  3478. // This function can assume that MCD entry point table is already
  3479. // initialized as we cannot get here without MCD already having been
  3480. // called.
  3481. //
  3482. ASSERTOPENGL(gpMcdTable,
  3483. "GenMcdProcessPrim: mcd32.dll not initialized\n");
  3484. #if DBG
  3485. {
  3486. LONG lOffset;
  3487. lOffset = (LONG) ((BYTE *) pa - (BYTE *) pMcdState->pMcdPrimBatch->pv);
  3488. ASSERTOPENGL(
  3489. (lOffset >= 0) &&
  3490. (lOffset < (LONG) pMcdState->pMcdPrimBatch->size),
  3491. "GenMcdProcessPrim: pa not in shared mem window\n");
  3492. }
  3493. #endif
  3494. //
  3495. // Before calling MCD to draw, flush state.
  3496. //
  3497. vFlushDirtyState(gengc);
  3498. #ifdef AUTOMATIC_SURF_LOCK
  3499. levels = gengc->gc.texture.ddtex.levels;
  3500. if (levels > 0 &&
  3501. gengc->gc.texture.ddtex.texobj.loadKey != 0)
  3502. {
  3503. pdds = gengc->gc.texture.ddtex.pdds;
  3504. }
  3505. else
  3506. #endif
  3507. {
  3508. levels = 0;
  3509. pdds = NULL;
  3510. }
  3511. return (POLYARRAY *)
  3512. (gpMcdTable->pMCDProcessBatch2)(&pMcdState->McdContext,
  3513. pMcdState->McdCmdBatch.pv,
  3514. pMcdState->pMcdPrimBatch->pv,
  3515. (PVOID) pa, levels, pdds,
  3516. cmdFlagsAll, primFlags,
  3517. pMCDTransform, pMCDMatChanges);
  3518. }
  3519. #endif