Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1362 lines
61 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * D3D SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: d3d.c
  8. *
  9. * Content: Main D3D capabilites and callback tables
  10. *
  11. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. //-----------------------------------------------------------------------------
  15. //
  16. // Certain conventions are followed in this sample driver in order to ease
  17. // the code reading process:
  18. //
  19. // - All driver function callbacks are prefixed with either D3D or DD. No other
  20. // functions start with such a prefix
  21. //
  22. // - Helper (or secondary) functions which are called from other places INSIDE
  23. // the driver (in different files) are prefixed with either _D3D or _DD
  24. //
  25. // - Helper functions called from within the same file are prefixed with __
  26. // (but not with __D3D or __DD !) so names as __CTX_CleanDirect3DContext arise
  27. //
  28. // - Data structures declared and used only be the driver are prefixed with P3
  29. //
  30. // - Very minor hungarian notation is used, basically in the form of prefixes
  31. // for DWORDs (dw), pointers (p), handles (h), and counters (i).
  32. //
  33. // - Global data items are prefixed with g_
  34. //
  35. // - This driver is intended to be source code compatible between the NT and
  36. // Win9x kernel display driver models. As such, most kernel structures retain
  37. // their Win9x name ( The DX8 d3dnthal.h shares the same names as the Win9x
  38. // d3dhal.h and for DX7 dx95type.h in the Win2K DDK will perform the
  39. // required level of translation). Major differences however are observed
  40. // using preprocessor #if statements.
  41. //
  42. //-----------------------------------------------------------------------------
  43. #include "glint.h"
  44. //-----------------------------------------------------------------------------
  45. // in-the-file nonexported forward declarations
  46. //-----------------------------------------------------------------------------
  47. void __D3D_BuildTextureFormatsP3(P3_THUNKEDDATA *pThisDisplay,
  48. DDSURFACEDESC TexFmt[MAX_TEXTURE_FORMAT],
  49. DWORD *pNumTextures);
  50. #if DX8_DDI
  51. void __D3D_Fill_DX8Caps(D3DCAPS8 *pd3d8caps,
  52. D3DDEVICEDESC_V1 *pDeviceDesc,
  53. D3DHAL_D3DEXTENDEDCAPS *pD3DEC,
  54. DDHALINFO *pDDHALInfo);
  55. #endif // DX8_DDI
  56. //-----------------------------------------------------------------------------
  57. // This structure contains all the the primitive capabilities (D3DPRIMCAPS)
  58. // this driver supports for triangles and lines. All of the information in this
  59. // table will be implementation specific according to the specifications of
  60. // the hardware.
  61. //-----------------------------------------------------------------------------
  62. #define P3RXTriCaps { \
  63. sizeof(D3DPRIMCAPS), \
  64. D3DPMISCCAPS_CULLCCW | /* MiscCaps */ \
  65. D3DPMISCCAPS_CULLCW | \
  66. D3DPMISCCAPS_CULLNONE | \
  67. D3DPMISCCAPS_MASKZ | \
  68. D3DPMISCCAPS_LINEPATTERNREP, \
  69. D3DPRASTERCAPS_DITHER | /* RasterCaps */ \
  70. D3DPRASTERCAPS_PAT | \
  71. D3DPRASTERCAPS_SUBPIXEL | \
  72. D3DPRASTERCAPS_ZTEST | \
  73. D3DPRASTERCAPS_FOGVERTEX | \
  74. D3DPRASTERCAPS_FOGTABLE | \
  75. D3DPRASTERCAPS_ZFOG | \
  76. D3DPRASTERCAPS_STIPPLE | \
  77. D3DPRASTERCAPS_MIPMAPLODBIAS, \
  78. D3DPCMPCAPS_NEVER | /* ZCmpCaps */ \
  79. D3DPCMPCAPS_LESS | \
  80. D3DPCMPCAPS_EQUAL | \
  81. D3DPCMPCAPS_LESSEQUAL | \
  82. D3DPCMPCAPS_GREATER | \
  83. D3DPCMPCAPS_NOTEQUAL | \
  84. D3DPCMPCAPS_GREATEREQUAL | \
  85. D3DPCMPCAPS_ALWAYS | \
  86. D3DPCMPCAPS_LESSEQUAL, \
  87. D3DPBLENDCAPS_ZERO | /* SourceBlendCaps */ \
  88. D3DPBLENDCAPS_ONE | \
  89. D3DPBLENDCAPS_SRCALPHA | \
  90. D3DPBLENDCAPS_INVSRCALPHA | \
  91. D3DPBLENDCAPS_DESTALPHA | \
  92. D3DPBLENDCAPS_INVDESTALPHA | \
  93. D3DPBLENDCAPS_DESTCOLOR | \
  94. D3DPBLENDCAPS_INVDESTCOLOR | \
  95. D3DPBLENDCAPS_SRCALPHASAT | \
  96. D3DPBLENDCAPS_BOTHSRCALPHA | \
  97. D3DPBLENDCAPS_BOTHINVSRCALPHA, \
  98. D3DPBLENDCAPS_ZERO | /* DestBlendCaps */ \
  99. D3DPBLENDCAPS_ONE | \
  100. D3DPBLENDCAPS_SRCCOLOR | \
  101. D3DPBLENDCAPS_INVSRCCOLOR | \
  102. D3DPBLENDCAPS_SRCALPHA | \
  103. D3DPBLENDCAPS_INVSRCALPHA | \
  104. D3DPBLENDCAPS_DESTALPHA | \
  105. D3DPBLENDCAPS_INVDESTALPHA, \
  106. D3DPCMPCAPS_NEVER | /* Alphatest caps */ \
  107. D3DPCMPCAPS_LESS | \
  108. D3DPCMPCAPS_EQUAL | \
  109. D3DPCMPCAPS_LESSEQUAL | \
  110. D3DPCMPCAPS_GREATER | \
  111. D3DPCMPCAPS_NOTEQUAL | \
  112. D3DPCMPCAPS_GREATEREQUAL | \
  113. D3DPCMPCAPS_ALWAYS, \
  114. D3DPSHADECAPS_COLORFLATRGB | /* ShadeCaps */ \
  115. D3DPSHADECAPS_COLORGOURAUDRGB | \
  116. D3DPSHADECAPS_SPECULARFLATRGB | \
  117. D3DPSHADECAPS_SPECULARGOURAUDRGB | \
  118. D3DPSHADECAPS_FOGFLAT | \
  119. D3DPSHADECAPS_FOGGOURAUD | \
  120. D3DPSHADECAPS_ALPHAFLATBLEND | \
  121. D3DPSHADECAPS_ALPHAGOURAUDBLEND | \
  122. D3DPSHADECAPS_ALPHAFLATSTIPPLED, \
  123. D3DPTEXTURECAPS_PERSPECTIVE | /* TextureCaps */ \
  124. D3DPTEXTURECAPS_ALPHA | \
  125. D3DPTEXTURECAPS_POW2 | \
  126. D3DPTEXTURECAPS_ALPHAPALETTE | \
  127. D3DPTEXTURECAPS_TRANSPARENCY, \
  128. D3DPTFILTERCAPS_NEAREST | /* TextureFilterCaps*/ \
  129. D3DPTFILTERCAPS_LINEAR | \
  130. D3DPTFILTERCAPS_MIPNEAREST | \
  131. D3DPTFILTERCAPS_MIPLINEAR | \
  132. D3DPTFILTERCAPS_LINEARMIPNEAREST | \
  133. D3DPTFILTERCAPS_LINEARMIPLINEAR | \
  134. D3DPTFILTERCAPS_MIPFPOINT | \
  135. D3DPTFILTERCAPS_MIPFLINEAR | \
  136. D3DPTFILTERCAPS_MAGFPOINT | \
  137. D3DPTFILTERCAPS_MAGFLINEAR | \
  138. D3DPTFILTERCAPS_MINFPOINT | \
  139. D3DPTFILTERCAPS_MINFLINEAR, \
  140. D3DPTBLENDCAPS_DECAL | /* TextureBlendCaps */ \
  141. D3DPTBLENDCAPS_DECALALPHA | \
  142. D3DPTBLENDCAPS_MODULATE | \
  143. D3DPTBLENDCAPS_MODULATEALPHA | \
  144. D3DPTBLENDCAPS_ADD | \
  145. D3DPTBLENDCAPS_COPY, \
  146. D3DPTADDRESSCAPS_WRAP | /* TextureAddressCaps */ \
  147. D3DPTADDRESSCAPS_MIRROR | \
  148. D3DPTADDRESSCAPS_CLAMP | \
  149. D3DPTADDRESSCAPS_INDEPENDENTUV, \
  150. 8, /* StippleWidth */ \
  151. 8 /* StippleHeight */ \
  152. }
  153. static D3DDEVICEDESC_V1 g_P3RXCaps = {
  154. sizeof(D3DDEVICEDESC_V1), // dwSize
  155. D3DDD_COLORMODEL | // dwFlags
  156. D3DDD_DEVCAPS |
  157. D3DDD_TRICAPS |
  158. D3DDD_LINECAPS |
  159. D3DDD_DEVICERENDERBITDEPTH |
  160. D3DDD_DEVICEZBUFFERBITDEPTH,
  161. D3DCOLOR_RGB , // dcmColorModel
  162. D3DDEVCAPS_CANRENDERAFTERFLIP | // devCaps
  163. D3DDEVCAPS_FLOATTLVERTEX |
  164. D3DDEVCAPS_SORTINCREASINGZ |
  165. D3DDEVCAPS_SORTEXACT |
  166. D3DDEVCAPS_TLVERTEXSYSTEMMEMORY |
  167. D3DDEVCAPS_EXECUTESYSTEMMEMORY |
  168. D3DDEVCAPS_TEXTUREVIDEOMEMORY |
  169. D3DDEVCAPS_DRAWPRIMTLVERTEX |
  170. D3DDEVCAPS_DRAWPRIMITIVES2 |
  171. #if DX7_VERTEXBUFFERS
  172. D3DDEVCAPS_HWVERTEXBUFFER |
  173. #endif
  174. D3DDEVCAPS_HWRASTERIZATION |
  175. D3DDEVCAPS_DRAWPRIMITIVES2EX,
  176. { sizeof(D3DTRANSFORMCAPS), 0 }, // transformCaps
  177. FALSE, // bClipping
  178. { sizeof(D3DLIGHTINGCAPS), 0 }, // lightingCaps
  179. P3RXTriCaps, // lineCaps
  180. P3RXTriCaps, // triCaps
  181. DDBD_16 | DDBD_32, // dwDeviceRenderBitDepth
  182. DDBD_16 | DDBD_32, // Z Bit depths
  183. 0, // dwMaxBufferSize
  184. 0 // dwMaxVertexCount
  185. };
  186. D3DHAL_D3DEXTENDEDCAPS gc_D3DEC = {
  187. sizeof(D3DHAL_D3DEXTENDEDCAPS), // dwSize // DX5
  188. 1, // dwMinTextureWidth
  189. 2048, // dwMaxTextureWidth
  190. 1, // dwMinTextureHeight
  191. 2048, // dwMaxTextureHeight
  192. 32, // dwMinStippleWidth
  193. 32, // dwMaxStippleWidth
  194. 32, // dwMinStippleHeight
  195. 32, // dwMaxStippleHeight
  196. 0, /*azn*/ // dwMaxTextureRepeat //DX6
  197. 0, // dwMaxTextureAspectRatio (no limit)
  198. 0, // dwMaxAnisotropy
  199. -4096.0f, // dvGuardBandLeft
  200. -4096.0f, // dvGuardBandTop
  201. 4096.0f, // dvGuardBandRight
  202. 4096.0f, // dvGuardBandBottom
  203. 0.0f, // dvExtentsAdjust
  204. D3DSTENCILCAPS_KEEP | // dwStencilCaps
  205. D3DSTENCILCAPS_ZERO |
  206. D3DSTENCILCAPS_REPLACE |
  207. D3DSTENCILCAPS_INCRSAT |
  208. D3DSTENCILCAPS_DECRSAT |
  209. D3DSTENCILCAPS_INVERT |
  210. D3DSTENCILCAPS_INCR |
  211. D3DSTENCILCAPS_DECR,
  212. 8, // dwFVFCaps
  213. D3DTEXOPCAPS_DISABLE | // dwTextureOpCaps
  214. D3DTEXOPCAPS_SELECTARG1 |
  215. D3DTEXOPCAPS_SELECTARG2 |
  216. D3DTEXOPCAPS_MODULATE |
  217. D3DTEXOPCAPS_MODULATE2X |
  218. D3DTEXOPCAPS_MODULATE4X |
  219. D3DTEXOPCAPS_ADD |
  220. D3DTEXOPCAPS_ADDSIGNED |
  221. D3DTEXOPCAPS_ADDSIGNED2X |
  222. D3DTEXOPCAPS_SUBTRACT |
  223. D3DTEXOPCAPS_ADDSMOOTH |
  224. D3DTEXOPCAPS_BLENDDIFFUSEALPHA |
  225. D3DTEXOPCAPS_BLENDTEXTUREALPHA |
  226. D3DTEXOPCAPS_BLENDFACTORALPHA |
  227. //@@BEGIN_DDKSPLIT
  228. #if 0
  229. // Fix texturestage DCT - seems we can't do this reliably
  230. D3DTEXOPCAPS_BLENDTEXTUREALPHAPM |
  231. D3DTEXOPCAPS_PREMODULATE |
  232. D3DTEXOPCAPS_BLENDCURRENTALPHA |
  233. #endif
  234. //@@END_DDKSPLIT
  235. D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
  236. D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
  237. D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
  238. D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA |
  239. D3DTEXOPCAPS_DOTPRODUCT3,
  240. 2, // wMaxTextureBlendStages
  241. 2, // wMaxSimultaneousTextures
  242. 0, // dwMaxActiveLights // DX7
  243. 0.0f, // dvMaxVertexW
  244. 0, // wMaxUserClipPlanes
  245. 0 // wMaxVertexBlendMatrices
  246. };
  247. #if DX8_DDI
  248. static D3DCAPS8 g_P3RX_D3DCaps8;
  249. #endif // DX8_DDI
  250. //--------------------------------------------------------
  251. // Supported ZBuffer/Stencil Formats by this hardware
  252. //--------------------------------------------------------
  253. #define P3RX_Z_FORMATS 4
  254. typedef struct
  255. {
  256. DWORD dwStructSize;
  257. DDPIXELFORMAT Format[P3RX_Z_FORMATS];
  258. } ZFormats;
  259. ZFormats P3RXZFormats =
  260. {
  261. P3RX_Z_FORMATS,
  262. {
  263. // Format 1 - 16 Bit Z Buffer, no stencil
  264. {
  265. sizeof(DDPIXELFORMAT),
  266. DDPF_ZBUFFER,
  267. 0,
  268. 16, // Total bits in buffer
  269. 0, // Stencil bits
  270. 0xFFFF, // Z mask
  271. 0, // Stencil mask
  272. 0
  273. },
  274. // Format 2 - 24 bit Z Buffer, 8 bit stencil
  275. {
  276. sizeof(DDPIXELFORMAT),
  277. DDPF_ZBUFFER | DDPF_STENCILBUFFER,
  278. 0,
  279. 32, // Total bits in buffer
  280. 8, // Stencil bits
  281. 0x00FFFFFF, // Z Mask
  282. 0xFF000000, // Stencil Mask
  283. 0
  284. },
  285. // Format 3 - 15 bit Z Buffer, 1 bit stencil
  286. {
  287. sizeof(DDPIXELFORMAT),
  288. DDPF_ZBUFFER | DDPF_STENCILBUFFER,
  289. 0,
  290. 16, // Total bits in buffer
  291. 1, // Stencil bits
  292. 0x7FFF, // Z Mask
  293. 0x8000, // Stencil mask
  294. 0
  295. },
  296. // Format 4 - 32 bit Z Buffer, no stencil
  297. {
  298. sizeof(DDPIXELFORMAT),
  299. DDPF_ZBUFFER,
  300. 0,
  301. 32, // Total bits in buffer
  302. 0, // Stencil bits
  303. 0xFFFFFFFF, // Z Mask
  304. 0, // Stencil Mask
  305. 0
  306. }
  307. }
  308. };
  309. #if DX8_DDI
  310. //----------------------------------------------------------------------------
  311. // Supported DX8 RenderTarget/Texture/ZBuffer/Stencil Formats by this hardware
  312. //----------------------------------------------------------------------------
  313. #if DX8_MULTISAMPLING
  314. // Note: For multisampling we need to setup appropriately both the rendertarget
  315. // and the depth buffer format's multisampling fields.
  316. #define D3DMULTISAMPLE_NUM_SAMPLES (1 << (D3DMULTISAMPLE_4_SAMPLES - 1))
  317. #else
  318. #define D3DMULTISAMPLE_NUM_SAMPLES D3DMULTISAMPLE_NONE
  319. #endif // DX8_MULTISAMPLING
  320. #define DX8_FORMAT(FourCC, Ops, dwMSFlipTypes) \
  321. { sizeof(DDPIXELFORMAT), DDPF_D3DFORMAT, (FourCC), 0, (Ops), \
  322. ((dwMSFlipTypes) & 0xFFFF ) << 16 | ((dwMSFlipTypes) & 0xFFFF), 0, 0 }
  323. DDPIXELFORMAT DX8FormatTable[] =
  324. {
  325. DX8_FORMAT(D3DFMT_X1R5G5B5, D3DFORMAT_OP_TEXTURE |
  326. D3DFORMAT_OP_VOLUMETEXTURE |
  327. D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET,
  328. D3DMULTISAMPLE_NUM_SAMPLES ),
  329. DX8_FORMAT(D3DFMT_R5G6B5, D3DFORMAT_OP_TEXTURE |
  330. D3DFORMAT_OP_VOLUMETEXTURE |
  331. D3DFORMAT_OP_DISPLAYMODE |
  332. D3DFORMAT_OP_3DACCELERATION |
  333. D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET,
  334. D3DMULTISAMPLE_NUM_SAMPLES ),
  335. DX8_FORMAT(D3DFMT_X8R8G8B8, D3DFORMAT_OP_TEXTURE |
  336. D3DFORMAT_OP_VOLUMETEXTURE |
  337. D3DFORMAT_OP_DISPLAYMODE |
  338. D3DFORMAT_OP_3DACCELERATION |
  339. D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET, 0),
  340. #ifdef DX7_PALETTETEXTURE
  341. DX8_FORMAT(D3DFMT_P8, D3DFORMAT_OP_TEXTURE |
  342. D3DFORMAT_OP_VOLUMETEXTURE, 0),
  343. #endif
  344. DX8_FORMAT(D3DFMT_A1R5G5B5, D3DFORMAT_OP_TEXTURE |
  345. D3DFORMAT_OP_VOLUMETEXTURE, 0),
  346. DX8_FORMAT(D3DFMT_A4R4G4B4, D3DFORMAT_OP_TEXTURE |
  347. D3DFORMAT_OP_VOLUMETEXTURE, 0),
  348. DX8_FORMAT(D3DFMT_A8R8G8B8, D3DFORMAT_OP_TEXTURE |
  349. D3DFORMAT_OP_VOLUMETEXTURE, 0),
  350. DX8_FORMAT(D3DFMT_A4L4, D3DFORMAT_OP_TEXTURE |
  351. D3DFORMAT_OP_VOLUMETEXTURE, 0),
  352. DX8_FORMAT(D3DFMT_A8L8, D3DFORMAT_OP_TEXTURE |
  353. D3DFORMAT_OP_VOLUMETEXTURE, 0),
  354. //@@BEGIN_DDKSPLIT
  355. // We are turning D3DFMT_A8 support OFF because the default color for
  356. // this format has been changed from white to black. The P3 has white
  357. // hardwired so there is no simple solution for this.
  358. #if 0
  359. DX8_FORMAT(D3DFMT_A8, D3DFORMAT_OP_TEXTURE |
  360. D3DFORMAT_OP_VOLUMETEXTURE, 0),
  361. #endif
  362. //@@END_DDKSPLIT
  363. DX8_FORMAT(D3DFMT_L8, D3DFORMAT_OP_TEXTURE |
  364. D3DFORMAT_OP_VOLUMETEXTURE, 0),
  365. DX8_FORMAT(D3DFMT_D16_LOCKABLE, D3DFORMAT_OP_ZSTENCIL |
  366. D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH ,
  367. D3DMULTISAMPLE_NUM_SAMPLES ),
  368. DX8_FORMAT(D3DFMT_D32, D3DFORMAT_OP_ZSTENCIL |
  369. D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH ,
  370. D3DMULTISAMPLE_NUM_SAMPLES ),
  371. DX8_FORMAT(D3DFMT_S8D24, D3DFORMAT_OP_ZSTENCIL |
  372. D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH ,
  373. D3DMULTISAMPLE_NUM_SAMPLES ),
  374. DX8_FORMAT(D3DFMT_S1D15, D3DFORMAT_OP_ZSTENCIL |
  375. D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH ,
  376. D3DMULTISAMPLE_NUM_SAMPLES )
  377. };
  378. #define DX8_FORMAT_COUNT (sizeof(DX8FormatTable) / sizeof(DX8FormatTable[0]))
  379. #endif // DX8_DDI
  380. #ifdef W95_DDRAW
  381. #define DDHAL_D3DBUFCALLBACKS DDHAL_DDEXEBUFCALLBACKS
  382. #endif
  383. //-----------------------------------------------------------------------------
  384. //
  385. // void _D3DHALCreateDriver
  386. //
  387. // _D3DHALCreateDriver is a helper function, not a callback.
  388. //
  389. // Its main purpouse is to centralize the first part of D3D initialization
  390. // (the second part is handled by _D3DGetDriverInfo) . _D3DHALCreateDriver:
  391. // Clears contexts
  392. // Fills entry points to D3D driver.
  393. // Generates and passes back texture formats.
  394. //
  395. // If the structures are succesfully created the internal pointers
  396. // (lpD3DGlobalDriverData, lpD3DHALCallbacks and (maybe) lpD3DBufCallbacks)
  397. // are updated to point to valid data structures.
  398. //
  399. //-----------------------------------------------------------------------------
  400. void
  401. _D3DHALCreateDriver(P3_THUNKEDDATA *pThisDisplay)
  402. {
  403. BOOL bRet;
  404. ULONG Result;
  405. D3DHAL_GLOBALDRIVERDATA* pD3DDriverData = NULL;
  406. D3DHAL_CALLBACKS* pD3DHALCallbacks = NULL;
  407. DDHAL_D3DBUFCALLBACKS* pD3DBufCallbacks = NULL;
  408. DBG_ENTRY(_D3DHALCreateDriver);
  409. // Verify if we have already created the necessary data. If so, don't go
  410. // again through this process.
  411. if ((pThisDisplay->lpD3DGlobalDriverData != 0) &&
  412. (pThisDisplay->lpD3DHALCallbacks != 0))
  413. {
  414. DISPDBG((WRNLVL,"D3D Data already created for this PDEV, "
  415. "not doing it again."));
  416. // we keep the same structure pointers to previously
  417. // created and stored in pThisDisplay
  418. DBG_EXIT(_D3DHALCreateDriver, 0);
  419. return;
  420. }
  421. else
  422. {
  423. DISPDBG((WRNLVL,"Creating D3D caps/callbacks for the "
  424. "first time on this PDEV"));
  425. }
  426. // We set the structure pointers to NULL in case an error happens and
  427. // we're forced to disable D3D support
  428. pThisDisplay->lpD3DGlobalDriverData = 0;
  429. pThisDisplay->lpD3DHALCallbacks = 0;
  430. pThisDisplay->lpD3DBufCallbacks = 0;
  431. // Initialize the context handle data structures (array) . We are careful
  432. // not to initialize the data structures twice (as between mode changes,
  433. // for example) as this info needs to be persistent between such events.
  434. _D3D_CTX_HandleInitialization();
  435. //-----------------------------------
  436. // Allocate necessary data structures
  437. //-----------------------------------
  438. // Initialize our pointers to global driver
  439. // data and to HAL callbacks to NULL
  440. pThisDisplay->pD3DDriverData16 = 0;
  441. pThisDisplay->pD3DDriverData32 = 0;
  442. pThisDisplay->pD3DHALCallbacks16 = 0;
  443. pThisDisplay->pD3DHALCallbacks32 = 0;
  444. pThisDisplay->pD3DHALExecuteCallbacks16 = 0;
  445. pThisDisplay->pD3DHALExecuteCallbacks32 = 0;
  446. // Allocate memory for the global driver data structure.
  447. SHARED_HEAP_ALLOC(&pThisDisplay->pD3DDriverData16,
  448. &pThisDisplay->pD3DDriverData32,
  449. sizeof(D3DHAL_GLOBALDRIVERDATA));
  450. if (pThisDisplay->pD3DDriverData32 == 0)
  451. {
  452. DISPDBG((ERRLVL, "ERROR: _D3DHALCreateDriver: "
  453. "Failed to allocate driverdata memory"));
  454. DBG_EXIT(_D3DHALCreateDriver,0);
  455. return;
  456. }
  457. DISPDBG((DBGLVL,"Allocated D3DDriverData Memory: p16:0x%x, p32:0x%x",
  458. pThisDisplay->pD3DDriverData16,
  459. pThisDisplay->pD3DDriverData32));
  460. // Allocate memory for the global HAL callback data structure.
  461. SHARED_HEAP_ALLOC(&pThisDisplay->pD3DHALCallbacks16,
  462. &pThisDisplay->pD3DHALCallbacks32,
  463. sizeof(D3DHAL_CALLBACKS));
  464. if (pThisDisplay->pD3DHALCallbacks32 == 0)
  465. {
  466. DISPDBG((ERRLVL, "ERROR: _D3DHALCreateDriver: "
  467. "Failed to allocate callback memory"));
  468. SHARED_HEAP_FREE(&pThisDisplay->pD3DDriverData16,
  469. &pThisDisplay->pD3DDriverData32,
  470. TRUE);
  471. DBG_EXIT(_D3DHALCreateDriver, 0);
  472. return;
  473. }
  474. DISPDBG((DBGLVL,"Allocated HAL Callbacks Memory: p16:0x%x, p32:0x%x",
  475. pThisDisplay->pD3DHALCallbacks16,
  476. pThisDisplay->pD3DHALCallbacks32));
  477. // Allocate memory for the global Vertex Buffer callback data structure.
  478. SHARED_HEAP_ALLOC(&pThisDisplay->pD3DHALExecuteCallbacks16,
  479. &pThisDisplay->pD3DHALExecuteCallbacks32,
  480. sizeof(DDHAL_D3DBUFCALLBACKS));
  481. if (pThisDisplay->pD3DHALExecuteCallbacks32 == 0)
  482. {
  483. DISPDBG((ERRLVL, "ERROR: _D3DHALCreateDriver: "
  484. "Failed to allocate callback memory"));
  485. SHARED_HEAP_FREE(&pThisDisplay->pD3DDriverData16,
  486. &pThisDisplay->pD3DDriverData32,
  487. TRUE);
  488. SHARED_HEAP_FREE(&pThisDisplay->pD3DHALCallbacks16,
  489. &pThisDisplay->pD3DHALCallbacks32,
  490. TRUE);
  491. DBG_EXIT(_D3DHALCreateDriver, 0);
  492. return;
  493. }
  494. DISPDBG((DBGLVL,"Allocated Vertex Buffer Callbacks Memory: "
  495. "p16:0x%x, p32:0x%x",
  496. pThisDisplay->pD3DHALExecuteCallbacks16,
  497. pThisDisplay->pD3DHALExecuteCallbacks32));
  498. //------------------------------------------------------
  499. // Fill in the data structures the driver has to provide
  500. //------------------------------------------------------
  501. // Get the Pointers
  502. pD3DDriverData = (D3DHAL_GLOBALDRIVERDATA*)pThisDisplay->pD3DDriverData32;
  503. pD3DHALCallbacks = (D3DHAL_CALLBACKS*)pThisDisplay->pD3DHALCallbacks32;
  504. pD3DBufCallbacks =
  505. (DDHAL_D3DBUFCALLBACKS *)pThisDisplay->pD3DHALExecuteCallbacks32;
  506. // Clear the global data
  507. memset(pD3DDriverData, 0, sizeof(D3DHAL_GLOBALDRIVERDATA));
  508. pD3DDriverData->dwSize = sizeof(D3DHAL_GLOBALDRIVERDATA);
  509. // Clear the HAL callbacks
  510. memset(pD3DHALCallbacks, 0, sizeof(D3DHAL_CALLBACKS));
  511. pD3DHALCallbacks->dwSize = sizeof(D3DHAL_CALLBACKS);
  512. // Clear the Vertex Buffer callbacks
  513. memset(pD3DBufCallbacks, 0, sizeof(DDHAL_D3DBUFCALLBACKS));
  514. pD3DBufCallbacks->dwSize = sizeof(DDHAL_D3DBUFCALLBACKS);
  515. // Report that we can texture from nonlocal vidmem only if the
  516. // card is an AGP one and AGP is enabed.
  517. if (pThisDisplay->bCanAGP)
  518. {
  519. g_P3RXCaps.dwDevCaps |= D3DDEVCAPS_TEXTURENONLOCALVIDMEM;
  520. }
  521. #if DX7_ANTIALIAS
  522. // Report we support fullscreen antialiasing
  523. g_P3RXCaps.dpcTriCaps.dwRasterCaps |=
  524. #if DX8_DDI
  525. D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE |
  526. #endif
  527. D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT;
  528. #endif // DX7_ANTIALIAS
  529. #if DX8_3DTEXTURES
  530. // Report we support 3D textures
  531. g_P3RXCaps.dpcTriCaps.dwTextureCaps |= D3DPTEXTURECAPS_VOLUMEMAP |
  532. D3DPTEXTURECAPS_VOLUMEMAP_POW2;
  533. #endif // DX8_3DTEXTURES
  534. //@@BEGIN_DDKSPLIT
  535. #if DX7_WBUFFER
  536. g_P3RXCaps.dpcTriCaps.dwRasterCaps |= D3DPRASTERCAPS_WBUFFER;
  537. #endif // DX7_WBUFFER
  538. //@@END_DDKSPLIT
  539. #if DX8_DDI
  540. if (TLCHIP_GAMMA)
  541. {
  542. // Enable handling of the new D3DRS_COLORWRITEENABLE
  543. // but only for GVX1 since VX1 has trouble with this at 16bpp
  544. g_P3RXCaps.dpcTriCaps.dwMiscCaps |= D3DPMISCCAPS_COLORWRITEENABLE;
  545. g_P3RXCaps.dpcLineCaps.dwMiscCaps |= D3DPMISCCAPS_COLORWRITEENABLE;
  546. }
  547. // Enable new cap for mipmap support
  548. g_P3RXCaps.dpcTriCaps.dwTextureCaps |= D3DPTEXTURECAPS_MIPMAP;
  549. g_P3RXCaps.dpcLineCaps.dwTextureCaps |= D3DPTEXTURECAPS_MIPMAP;
  550. #endif // DX8_DDI
  551. //---------------------------
  552. // Fill in global driver data
  553. //---------------------------
  554. // Hardware caps supoorted
  555. pD3DDriverData->dwNumVertices = 0;
  556. pD3DDriverData->dwNumClipVertices = 0;
  557. pD3DDriverData->hwCaps = g_P3RXCaps;
  558. // Build a table with the texture formats supported. Store in pThisDisplay
  559. // as we will need this also for DdCanCreateSurface. ( Notice that since
  560. // _D3DHALCreateDriver will be called in every driver load or mode change,
  561. // we will have valid TextureFormats in pThisDisplay whenever
  562. // DdCanCreateSurface is called )
  563. __D3D_BuildTextureFormatsP3(pThisDisplay,
  564. &pThisDisplay->TextureFormats[0],
  565. &pThisDisplay->dwNumTextureFormats);
  566. pD3DDriverData->dwNumTextureFormats = pThisDisplay->dwNumTextureFormats;
  567. pD3DDriverData->lpTextureFormats = pThisDisplay->TextureFormats;
  568. //---------------------------------------
  569. // Fill in context handling HAL callbacks
  570. //---------------------------------------
  571. pD3DHALCallbacks->ContextCreate = D3DContextCreate;
  572. pD3DHALCallbacks->ContextDestroy = D3DContextDestroy;
  573. //---------------------------------------------------
  574. // Fill in Vertex Buffer callbacks pointers and flags
  575. //---------------------------------------------------
  576. #if !DX7_VERTEXBUFFERS
  577. // We won't use this structure at all so delete it
  578. SHARED_HEAP_FREE(&pThisDisplay->pD3DHALExecuteCallbacks16,
  579. &pThisDisplay->pD3DHALExecuteCallbacks32,
  580. TRUE);
  581. pD3DBufCallbacks = NULL;
  582. //@@BEGIN_DDKSPLIT
  583. #else
  584. pD3DBufCallbacks->dwSize = sizeof(DDHAL_D3DBUFCALLBACKS);
  585. pD3DBufCallbacks->dwFlags = DDHAL_EXEBUFCB32_CANCREATEEXEBUF |
  586. DDHAL_EXEBUFCB32_CREATEEXEBUF |
  587. DDHAL_EXEBUFCB32_DESTROYEXEBUF |
  588. DDHAL_EXEBUFCB32_LOCKEXEBUF |
  589. DDHAL_EXEBUFCB32_UNLOCKEXEBUF;
  590. #if WNT_DDRAW
  591. // Execute buffer callbacks for WinNT
  592. pD3DBufCallbacks->CanCreateD3DBuffer = D3DCanCreateD3DBuffer;
  593. pD3DBufCallbacks->CreateD3DBuffer = D3DCreateD3DBuffer;
  594. pD3DBufCallbacks->DestroyD3DBuffer = D3DDestroyD3DBuffer;
  595. pD3DBufCallbacks->LockD3DBuffer = D3DLockD3DBuffer;
  596. pD3DBufCallbacks->UnlockD3DBuffer = D3DUnlockD3DBuffer;
  597. #else
  598. // Execute buffer callbacks for Win9x
  599. pD3DBufCallbacks->CanCreateExecuteBuffer = D3DCanCreateD3DBuffer;
  600. pD3DBufCallbacks->CreateExecuteBuffer = D3DCreateD3DBuffer;
  601. pD3DBufCallbacks->DestroyExecuteBuffer = D3DDestroyD3DBuffer;
  602. pD3DBufCallbacks->LockExecuteBuffer = D3DLockD3DBuffer;
  603. pD3DBufCallbacks->UnlockExecuteBuffer = D3DUnlockD3DBuffer;
  604. #endif // WNT_DDRAW
  605. //@@END_DDKSPLIT
  606. #endif // DX7_VERTEXBUFFERS
  607. //---------------------------------------------------------
  608. // We return with updated pThisDisplay internal pointers to
  609. // the driver data, HAL and Vertex Buffer structures.
  610. //---------------------------------------------------------
  611. pThisDisplay->lpD3DGlobalDriverData = (ULONG_PTR)pD3DDriverData;
  612. pThisDisplay->lpD3DHALCallbacks = (ULONG_PTR)pD3DHALCallbacks;
  613. pThisDisplay->lpD3DBufCallbacks = (ULONG_PTR)pD3DBufCallbacks;
  614. #ifndef WNT_DDRAW
  615. //
  616. // Set up the same information in DDHALINFO
  617. //
  618. //@@BEGIN_DDKSPLIT
  619. #ifdef W95_DDRAW
  620. //
  621. // Our {in|ex}ternal header files are not completely consistent regarding
  622. // these 2 callback functions, internally they are typed function pointers,
  623. // externally they are just DWORDs.
  624. //
  625. pThisDisplay->ddhi32.lpD3DGlobalDriverData = pD3DDriverData;
  626. pThisDisplay->ddhi32.lpD3DHALCallbacks = pD3DHALCallbacks;
  627. #else
  628. //@@END_DDKSPLIT
  629. pThisDisplay->ddhi32.lpD3DGlobalDriverData = (ULONG_PTR)pD3DDriverData;
  630. pThisDisplay->ddhi32.lpD3DHALCallbacks = (ULONG_PTR)pD3DHALCallbacks;
  631. //@@BEGIN_DDKSPLIT
  632. #endif
  633. //@@END_DDKSPLIT
  634. pThisDisplay->ddhi32.lpDDExeBufCallbacks = pD3DBufCallbacks;
  635. #endif
  636. DBG_EXIT(_D3DHALCreateDriver,0);
  637. return;
  638. } // _D3DHALCreateDriver
  639. //-----------------------------------------------------------------------------
  640. //
  641. // void _D3DGetDriverInfo
  642. //
  643. // _D3DGetDriverInfo is a helper function called by DdGetDriverInfo , not a
  644. // callback. Its main purpouse is to centralize the second part of D3D
  645. // initialization (the first part is handled by _D3DHALCreateDriver) .
  646. //
  647. // _D3DGetDriverInfo handles the
  648. //
  649. // GUID_D3DExtendedCaps
  650. // GUID_D3DParseUnknownCommandCallback
  651. // GUID_D3DCallbacks3
  652. // GUID_ZPixelFormats
  653. // GUID_Miscellaneous2Callbacks
  654. //
  655. // GUIDs and fills all the relevant information associated to them.
  656. // GUID_D3DCallbacks2 is not handled at all because it is a legacy GUID.
  657. //
  658. //-----------------------------------------------------------------------------
  659. void
  660. _D3DGetDriverInfo(
  661. LPDDHAL_GETDRIVERINFODATA lpData)
  662. {
  663. DWORD dwSize;
  664. P3_THUNKEDDATA *pThisDisplay;
  665. DBG_ENTRY(_D3DGetDriverInfo);
  666. // Get a pointer to the chip we are on.
  667. #if WNT_DDRAW
  668. pThisDisplay = (P3_THUNKEDDATA*)(((PPDEV)(lpData->dhpdev))->thunkData);
  669. #else
  670. pThisDisplay = (P3_THUNKEDDATA*)lpData->dwContext;
  671. if (! pThisDisplay)
  672. {
  673. pThisDisplay = g_pDriverData;
  674. }
  675. #endif
  676. // Fill in required Miscellaneous2 callbacks
  677. if ( MATCH_GUID(lpData->guidInfo, GUID_Miscellaneous2Callbacks))
  678. {
  679. DDHAL_DDMISCELLANEOUS2CALLBACKS DDMisc2;
  680. DISPDBG((DBGLVL, " GUID_Miscellaneous2Callbacks"));
  681. memset(&DDMisc2, 0, sizeof(DDMisc2));
  682. dwSize = min(lpData->dwExpectedSize,
  683. sizeof(DDHAL_DDMISCELLANEOUS2CALLBACKS));
  684. lpData->dwActualSize = sizeof(DDHAL_DDMISCELLANEOUS2CALLBACKS);
  685. ASSERTDD((lpData->dwExpectedSize ==
  686. sizeof(DDHAL_DDMISCELLANEOUS2CALLBACKS)),
  687. "ERROR: Callbacks 2 size incorrect!");
  688. DDMisc2.dwSize = dwSize;
  689. DDMisc2.dwFlags = DDHAL_MISC2CB32_GETDRIVERSTATE |
  690. DDHAL_MISC2CB32_CREATESURFACEEX |
  691. DDHAL_MISC2CB32_DESTROYDDLOCAL;
  692. DDMisc2.GetDriverState = D3DGetDriverState;
  693. DDMisc2.CreateSurfaceEx = D3DCreateSurfaceEx;
  694. DDMisc2.DestroyDDLocal = D3DDestroyDDLocal;
  695. memcpy(lpData->lpvData, &DDMisc2, dwSize);
  696. lpData->ddRVal = DD_OK;
  697. }
  698. // Fill in the extended caps
  699. if (MATCH_GUID((lpData->guidInfo), GUID_D3DExtendedCaps) )
  700. {
  701. DISPDBG((DBGLVL, " GUID_D3DExtendedCaps"));
  702. dwSize = min(lpData->dwExpectedSize, sizeof(D3DHAL_D3DEXTENDEDCAPS));
  703. lpData->dwActualSize = sizeof(D3DHAL_D3DEXTENDEDCAPS);
  704. memcpy(lpData->lpvData, &gc_D3DEC, sizeof(gc_D3DEC) );
  705. lpData->ddRVal = DD_OK;
  706. }
  707. // Grab the pointer to the ParseUnknownCommand OS callback
  708. if ( MATCH_GUID(lpData->guidInfo, GUID_D3DParseUnknownCommandCallback) )
  709. {
  710. DISPDBG((DBGLVL, "Get D3DParseUnknownCommandCallback"));
  711. *(ULONG_PTR *)(&pThisDisplay->pD3DParseUnknownCommand) =
  712. (ULONG_PTR)lpData->lpvData;
  713. ASSERTDD((pThisDisplay->pD3DParseUnknownCommand),
  714. "D3D ParseUnknownCommand callback == NULL");
  715. lpData->ddRVal = DD_OK;
  716. }
  717. // Fill in ZBuffer/Stencil formats supported. If you don't respond to
  718. // this GUID, ZBuffer formats will be inferred from the D3DDEVICEDESC
  719. // copied in _D3DHALCreateDriver
  720. if ( MATCH_GUID(lpData->guidInfo, GUID_ZPixelFormats))
  721. {
  722. DISPDBG((DBGLVL, " GUID_ZPixelFormats"));
  723. dwSize = min(lpData->dwExpectedSize, sizeof(P3RXZFormats));
  724. lpData->dwActualSize = sizeof(P3RXZFormats);
  725. memcpy(lpData->lpvData, &P3RXZFormats, dwSize);
  726. lpData->ddRVal = DD_OK;
  727. }
  728. // Fill in required D3DCallbacks3 callbacks
  729. if ( MATCH_GUID(lpData->guidInfo, GUID_D3DCallbacks3) )
  730. {
  731. D3DHAL_CALLBACKS3 D3DCallbacks3;
  732. memset(&D3DCallbacks3, 0, sizeof(D3DCallbacks3));
  733. DISPDBG((DBGLVL, " GUID_D3DCallbacks3"));
  734. dwSize = min(lpData->dwExpectedSize, sizeof(D3DHAL_CALLBACKS3));
  735. lpData->dwActualSize = sizeof(D3DHAL_CALLBACKS3);
  736. ASSERTDD((lpData->dwExpectedSize == sizeof(D3DHAL_CALLBACKS3)),
  737. "ERROR: Callbacks 3 size incorrect!");
  738. D3DCallbacks3.dwSize = dwSize;
  739. D3DCallbacks3.dwFlags = D3DHAL3_CB32_VALIDATETEXTURESTAGESTATE |
  740. D3DHAL3_CB32_DRAWPRIMITIVES2;
  741. D3DCallbacks3.DrawPrimitives2 = D3DDrawPrimitives2_P3;
  742. D3DCallbacks3.ValidateTextureStageState = D3DValidateDeviceP3;
  743. memcpy(lpData->lpvData, &D3DCallbacks3, dwSize);
  744. lpData->ddRVal = DD_OK;
  745. }
  746. // Check for calls to GetDriverInfo2
  747. // Notice : GUID_GetDriverInfo2 has the same value as GUID_DDStereoMode
  748. #if DX8_DDI
  749. if ( MATCH_GUID(lpData->guidInfo, GUID_GetDriverInfo2) )
  750. #else
  751. if ( MATCH_GUID(lpData->guidInfo, GUID_DDStereoMode) )
  752. #endif
  753. {
  754. #if DX8_DDI
  755. // Make sure this is actually a call to GetDriverInfo2
  756. // ( and not a call to DDStereoMode!)
  757. if (D3DGDI_IS_GDI2(lpData))
  758. {
  759. // Yes, its a call to GetDriverInfo2, fetch the
  760. // DD_GETDRIVERINFO2DATA data structure.
  761. DD_GETDRIVERINFO2DATA* pgdi2 = D3DGDI_GET_GDI2_DATA(lpData);
  762. DD_GETFORMATCOUNTDATA* pgfcd;
  763. DD_GETFORMATDATA* pgfd;
  764. DD_DXVERSION* pdxv;
  765. // What type of request is this?
  766. switch (pgdi2->dwType)
  767. {
  768. case D3DGDI2_TYPE_DXVERSION:
  769. // This is a way for a driver on NT to find out the DX-Runtime
  770. // version. This information is provided to a new driver (i.e.
  771. // one that exposes GETDRIVERINFO2) for DX7 applications and
  772. // DX8 applications. And you should get x0000800 for
  773. // dwDXVersion; or more accurately, you should get
  774. // DD_RUNTIME_VERSION which is defined in ddrawi.h.
  775. pdxv = (DD_DXVERSION*)pgdi2;
  776. pThisDisplay->dwDXVersion = pdxv->dwDXVersion;
  777. lpData->dwActualSize = sizeof(DD_DXVERSION);
  778. lpData->ddRVal = DD_OK;
  779. break;
  780. case D3DGDI2_TYPE_GETFORMATCOUNT:
  781. {
  782. // Its a request for the number of texture formats
  783. // we support. Get the extended data structure so
  784. // we can fill in the format count field.
  785. pgfcd = (DD_GETFORMATCOUNTDATA*)pgdi2;
  786. pgfcd->dwFormatCount = DX8_FORMAT_COUNT;
  787. lpData->dwActualSize = sizeof(DD_GETFORMATCOUNTDATA);
  788. lpData->ddRVal = DD_OK;
  789. }
  790. break;
  791. case D3DGDI2_TYPE_GETFORMAT:
  792. {
  793. // Its a request for a particular format we support.
  794. // Get the extended data structure so we can fill in
  795. // the format field.
  796. pgfd = (DD_GETFORMATDATA*)pgdi2;
  797. // Initialize the surface description and copy over
  798. // the pixel format from out pixel format table.
  799. memcpy(&pgfd->format,
  800. &DX8FormatTable[pgfd->dwFormatIndex],
  801. sizeof(pgfd->format));
  802. lpData->dwActualSize = sizeof(DD_GETFORMATDATA);
  803. lpData->ddRVal = DD_OK;
  804. }
  805. break;
  806. case D3DGDI2_TYPE_GETD3DCAPS8:
  807. {
  808. // The runtime is requesting the DX8 D3D caps
  809. int i;
  810. size_t copySize;
  811. // We will populate this caps as much as we can
  812. // from the DX7 caps structure(s). ( We need anyway
  813. // to be able to report DX7 caps for DX7 apps )
  814. __D3D_Fill_DX8Caps(&g_P3RX_D3DCaps8,
  815. &g_P3RXCaps,
  816. &gc_D3DEC,
  817. &pThisDisplay->ddhi32);
  818. // And now we fill anything that might not be there
  819. // These fields are new and absent from any other legacy
  820. // structure
  821. g_P3RX_D3DCaps8.DeviceType = D3DDEVTYPE_HAL; // Device Info
  822. g_P3RX_D3DCaps8.AdapterOrdinal = 0;
  823. #if DX_NOT_SUPPORTED_FEATURE
  824. // NOTE: In some beta releases of this sample driver we
  825. // used to setup bit caps for using it as a pure
  826. // device (D3DDEVCAPS_PUREDEVICE). On the final
  827. // DX8 release pure devices are not allowed on
  828. // non-TnL/non hwvp parts as they don't give any
  829. // real advantage over non-pure ones.
  830. g_P3RX_D3DCaps8.DevCaps |= D3DDEVCAPS_PUREDEVICE;
  831. #endif
  832. #if DX8_3DTEXTURES
  833. // On Windows XP the ability to lock just a subvolume of a
  834. // volume texture has been introduced in DX8.1 (Windows 2000
  835. // will ignore it)
  836. g_P3RX_D3DCaps8.DevCaps |= D3DDEVCAPS_SUBVOLUMELOCK;
  837. #endif // DX8_3DTEXTURES
  838. // Indicating that the GDI part of the driver can change
  839. // gamma ramp while running in full-screen mode.
  840. g_P3RX_D3DCaps8.Caps2 |= D3DCAPS2_FULLSCREENGAMMA;
  841. // The following field can/should be left as 0 as the
  842. // runtime will field them by itself.
  843. g_P3RX_D3DCaps8.Caps3 = 0;
  844. g_P3RX_D3DCaps8.PresentationIntervals = 0;
  845. #if DX_NOT_SUPPORTED_FEATURE
  846. // If your hw/driver supports colored cursor without
  847. // limitations then set these caps as below. We don't
  848. // do this in our driver because we have a hw limitation
  849. // of 16 colors on the cursor. WHQL tests therefore
  850. // fail because of this limitation
  851. g_P3RX_D3DCaps8.CursorCaps = D3DCURSORCAPS_COLOR;
  852. // Signal that the driver does support hw cursors
  853. // both for hi resolution modes ( height >= 400) and
  854. // for low resolution modes as well.
  855. g_P3RX_D3DCaps8.CursorCaps |= D3DCURSORCAPS_LOWRES;
  856. #else
  857. // We have some limitations (read above) in the Perm3
  858. // hardware so we're not supporting these caps here
  859. g_P3RX_D3DCaps8.CursorCaps = 0;
  860. #endif
  861. // Miscellanneous settings new DX8 features as
  862. // pointsprites, multistreaming, 3D textures,
  863. // pixelshaders and vertex shaders
  864. g_P3RX_D3DCaps8.MaxVertexIndex = 0x000FFFFF;
  865. #if DX8_POINTSPRITES
  866. // Notify we can handle pointsprite size
  867. g_P3RX_D3DCaps8.FVFCaps |= D3DFVFCAPS_PSIZE;
  868. // Notice that the MaxPointSize has to be at least 16
  869. // per the DX8 specification for pointsprites.
  870. g_P3RX_D3DCaps8.MaxPointSize = P3_MAX_POINTSPRITE_SIZE;
  871. #endif
  872. // Any DX8 driver must declare it suppports
  873. // AT LEAST 1 stream. Otherwise its used as a DX7 driver.
  874. g_P3RX_D3DCaps8.MaxStreams = 1;
  875. g_P3RX_D3DCaps8.MaxVertexBlendMatrixIndex = 0;
  876. // NOTE: It is essential that the macros D3DVS_VERSION
  877. // and D3DPS_VERSION be used to intialize the vertex
  878. // and pixel shader version respecitively. The format
  879. // of the version DWORD is complex so please don't try
  880. // and build the version DWORD manually.
  881. g_P3RX_D3DCaps8.VertexShaderVersion = D3DVS_VERSION(0, 0);
  882. g_P3RX_D3DCaps8.PixelShaderVersion = D3DPS_VERSION(0, 0);
  883. #if DX8_3DTEXTURES
  884. g_P3RX_D3DCaps8.MaxVolumeExtent = 2048;
  885. #endif
  886. // D3DPTFILTERCAPS for IDirect3DCubeTexture8's
  887. g_P3RX_D3DCaps8.CubeTextureFilterCaps = 0;
  888. // D3DLINECAPS
  889. g_P3RX_D3DCaps8.LineCaps = D3DLINECAPS_TEXTURE |
  890. D3DLINECAPS_ZTEST |
  891. D3DLINECAPS_BLEND |
  892. D3DLINECAPS_ALPHACMP |
  893. D3DLINECAPS_FOG;
  894. // max number of primitives per DrawPrimitive call
  895. g_P3RX_D3DCaps8.MaxPrimitiveCount = 0x000FFFFF;
  896. // max value of pixel shade
  897. g_P3RX_D3DCaps8.MaxPixelShaderValue = 0;
  898. // max stride for SetStreamSource
  899. // we will use this defualt value for now
  900. g_P3RX_D3DCaps8.MaxStreamStride = 256;
  901. // number of vertex shader constant
  902. g_P3RX_D3DCaps8.MaxVertexShaderConst = 0;
  903. #if DX8_3DTEXTURES
  904. g_P3RX_D3DCaps8.VolumeTextureFilterCaps =
  905. D3DPTFILTERCAPS_MINFPOINT |
  906. D3DPTFILTERCAPS_MAGFPOINT;
  907. g_P3RX_D3DCaps8.VolumeTextureAddressCaps =
  908. D3DPTADDRESSCAPS_WRAP |
  909. D3DPTADDRESSCAPS_MIRROR |
  910. D3DPTADDRESSCAPS_CLAMP;
  911. #endif // DX8_3DTEXTURES
  912. // It should be noted that the dwExpectedSize field
  913. // of DD_GETDRIVERINFODATA is not used for
  914. // GetDriverInfo2 calls and should be ignored.
  915. copySize = min(sizeof(g_P3RX_D3DCaps8),
  916. pgdi2->dwExpectedSize);
  917. memcpy(lpData->lpvData, &g_P3RX_D3DCaps8, copySize);
  918. lpData->dwActualSize = copySize;
  919. lpData->ddRVal = DD_OK;
  920. }
  921. default:
  922. // Default behavior for any other type.
  923. break;
  924. }
  925. }
  926. else
  927. #endif // DX8_DDI
  928. {
  929. #if WNT_DDRAW
  930. #if DX7_STEREO
  931. PDD_STEREOMODE pDDStereoMode;
  932. // Permedia3 supports all modes as stereo modes.
  933. // for test purposes, we restrict them to something
  934. // larger than 320x240
  935. //
  936. // note: this GUID_DDStereoMode is only used on NT to
  937. // report stereo modes. There is no need to implement
  938. // it in win9x drivers. Win9x drivers report stereo
  939. // modes by setting the DDMODEINFO_STEREO bit in the
  940. // dwFlags member of the DDHALMODEINFO structure.
  941. // It is also recommended to report DDMODEINFO_MAXREFRESH
  942. // for stereo modes when running under a runtime >= DX7 to
  943. // allow applications to select higher refresh rates for
  944. // stereo modes.
  945. //
  946. if (lpData->dwExpectedSize >= sizeof(PDD_STEREOMODE))
  947. {
  948. pDDStereoMode = (PDD_STEREOMODE)lpData->lpvData;
  949. pDDStereoMode->bSupported =
  950. _DD_bIsStereoMode(pThisDisplay,
  951. pDDStereoMode->dwWidth,
  952. pDDStereoMode->dwHeight,
  953. pDDStereoMode->dwBpp);
  954. DISPDBG((DBGLVL," GUID_DDStereoMode(%d,%d,%d,%d=%d)",
  955. pDDStereoMode->dwWidth,
  956. pDDStereoMode->dwHeight,
  957. pDDStereoMode->dwBpp,
  958. pDDStereoMode->dwRefreshRate,
  959. pDDStereoMode->bSupported));
  960. lpData->dwActualSize = sizeof(DD_STEREOMODE);
  961. lpData->ddRVal = DD_OK;
  962. }
  963. #endif // DX7_STEREO
  964. #endif // WNT_DDRAW
  965. }
  966. }
  967. DBG_EXIT(_D3DGetDriverInfo, 0);
  968. } // _D3DGetDriverInfo
  969. //-----------------------------------------------------------------------------
  970. //
  971. // __D3D_BuildTextureFormatsP3
  972. //
  973. // Fills a list of texture formats in.
  974. // Returns the number of formats specified.
  975. //
  976. //-----------------------------------------------------------------------------
  977. void
  978. __D3D_BuildTextureFormatsP3(
  979. P3_THUNKEDDATA *pThisDisplay,
  980. DDSURFACEDESC TexFmt[MAX_TEXTURE_FORMAT],
  981. DWORD *pNumTextures)
  982. {
  983. int i;
  984. // Initialise the defaults
  985. for (i = 0; i < MAX_TEXTURE_FORMAT; i++)
  986. {
  987. TexFmt[i].dwSize = sizeof(DDSURFACEDESC);
  988. TexFmt[i].dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT;
  989. TexFmt[i].dwHeight = 0;
  990. TexFmt[i].dwWidth = 0;
  991. TexFmt[i].lPitch = 0;
  992. TexFmt[i].dwBackBufferCount = 0;
  993. TexFmt[i].dwZBufferBitDepth = 0;
  994. TexFmt[i].dwReserved = 0;
  995. TexFmt[i].lpSurface = 0;
  996. TexFmt[i].ddckCKDestOverlay.dwColorSpaceLowValue = 0;
  997. TexFmt[i].ddckCKDestOverlay.dwColorSpaceHighValue = 0;
  998. TexFmt[i].ddckCKDestBlt.dwColorSpaceLowValue = 0;
  999. TexFmt[i].ddckCKDestBlt.dwColorSpaceHighValue = 0;
  1000. TexFmt[i].ddckCKSrcOverlay.dwColorSpaceLowValue = 0;
  1001. TexFmt[i].ddckCKSrcOverlay.dwColorSpaceHighValue = 0;
  1002. TexFmt[i].ddckCKSrcBlt.dwColorSpaceLowValue = 0;
  1003. TexFmt[i].ddckCKSrcBlt.dwColorSpaceHighValue = 0;
  1004. TexFmt[i].ddsCaps.dwCaps = DDSCAPS_TEXTURE;
  1005. }
  1006. i = 0;
  1007. // 5:5:5 RGB
  1008. ZeroMemory(&TexFmt[i].ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  1009. TexFmt[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  1010. TexFmt[i].ddpfPixelFormat.dwFourCC = 0;
  1011. TexFmt[i].ddpfPixelFormat.dwFlags = DDPF_RGB;
  1012. TexFmt[i].ddpfPixelFormat.dwRGBBitCount = 16;
  1013. TexFmt[i].ddpfPixelFormat.dwRBitMask = 0x7C00;
  1014. TexFmt[i].ddpfPixelFormat.dwGBitMask = 0x03E0;
  1015. TexFmt[i].ddpfPixelFormat.dwBBitMask = 0x001F;
  1016. TexFmt[i].ddpfPixelFormat.dwRGBAlphaBitMask = 0;
  1017. i++;
  1018. // 8:8:8 RGB
  1019. ZeroMemory(&TexFmt[i].ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  1020. TexFmt[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  1021. TexFmt[i].ddpfPixelFormat.dwFourCC = 0;
  1022. TexFmt[i].ddpfPixelFormat.dwFlags = DDPF_RGB;
  1023. TexFmt[i].ddpfPixelFormat.dwRGBBitCount = 32;
  1024. TexFmt[i].ddpfPixelFormat.dwRBitMask = 0xff0000;
  1025. TexFmt[i].ddpfPixelFormat.dwGBitMask = 0xff00;
  1026. TexFmt[i].ddpfPixelFormat.dwBBitMask = 0xff;
  1027. TexFmt[i].ddpfPixelFormat.dwRGBAlphaBitMask = 0;
  1028. i++;
  1029. // 1:5:5:5 ARGB
  1030. ZeroMemory(&TexFmt[i].ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  1031. TexFmt[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  1032. TexFmt[i].ddpfPixelFormat.dwFourCC = 0;
  1033. TexFmt[i].ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
  1034. TexFmt[i].ddpfPixelFormat.dwRGBBitCount = 16;
  1035. TexFmt[i].ddpfPixelFormat.dwRBitMask = 0x7C00;
  1036. TexFmt[i].ddpfPixelFormat.dwGBitMask = 0x03E0;
  1037. TexFmt[i].ddpfPixelFormat.dwBBitMask = 0x001F;
  1038. TexFmt[i].ddpfPixelFormat.dwRGBAlphaBitMask = 0x8000;
  1039. i++;
  1040. // 4:4:4:4 ARGB
  1041. ZeroMemory(&TexFmt[i].ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  1042. TexFmt[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  1043. TexFmt[i].ddpfPixelFormat.dwFourCC = 0;
  1044. TexFmt[i].ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
  1045. TexFmt[i].ddpfPixelFormat.dwRGBBitCount = 16;
  1046. TexFmt[i].ddpfPixelFormat.dwRBitMask = 0xf00;
  1047. TexFmt[i].ddpfPixelFormat.dwGBitMask = 0xf0;
  1048. TexFmt[i].ddpfPixelFormat.dwBBitMask = 0xf;
  1049. TexFmt[i].ddpfPixelFormat.dwRGBAlphaBitMask = 0xf000;
  1050. i++;
  1051. // 8:8:8:8 ARGB
  1052. ZeroMemory(&TexFmt[i].ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  1053. TexFmt[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  1054. TexFmt[i].ddpfPixelFormat.dwFourCC = 0;
  1055. TexFmt[i].ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
  1056. TexFmt[i].ddpfPixelFormat.dwRGBBitCount = 32;
  1057. TexFmt[i].ddpfPixelFormat.dwRBitMask = 0xff0000;
  1058. TexFmt[i].ddpfPixelFormat.dwGBitMask = 0xff00;
  1059. TexFmt[i].ddpfPixelFormat.dwBBitMask = 0xff;
  1060. TexFmt[i].ddpfPixelFormat.dwRGBAlphaBitMask = 0xff000000;
  1061. i++;
  1062. // 5:6:5
  1063. ZeroMemory(&TexFmt[i].ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  1064. TexFmt[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  1065. TexFmt[i].ddpfPixelFormat.dwFourCC = 0;
  1066. TexFmt[i].ddpfPixelFormat.dwFlags = DDPF_RGB;
  1067. TexFmt[i].ddpfPixelFormat.dwRGBBitCount = 16;
  1068. TexFmt[i].ddpfPixelFormat.dwRBitMask = 0xF800;
  1069. TexFmt[i].ddpfPixelFormat.dwGBitMask = 0x07E0;
  1070. TexFmt[i].ddpfPixelFormat.dwBBitMask = 0x001F;
  1071. TexFmt[i].ddpfPixelFormat.dwRGBAlphaBitMask = 0;
  1072. i++;
  1073. // A4L4
  1074. ZeroMemory(&TexFmt[i].ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  1075. TexFmt[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  1076. TexFmt[i].ddpfPixelFormat.dwFourCC = 0;
  1077. TexFmt[i].ddpfPixelFormat.dwFlags = DDPF_LUMINANCE | DDPF_ALPHAPIXELS;
  1078. TexFmt[i].ddpfPixelFormat.dwLuminanceBitCount = 8;
  1079. TexFmt[i].ddpfPixelFormat.dwLuminanceBitMask = 0x0F;
  1080. TexFmt[i].ddpfPixelFormat.dwLuminanceAlphaBitMask = 0xF0;
  1081. i++;
  1082. // A8L8
  1083. ZeroMemory(&TexFmt[i].ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  1084. TexFmt[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  1085. TexFmt[i].ddpfPixelFormat.dwFourCC = 0;
  1086. TexFmt[i].ddpfPixelFormat.dwFlags = DDPF_LUMINANCE | DDPF_ALPHAPIXELS;
  1087. TexFmt[i].ddpfPixelFormat.dwLuminanceBitCount = 16;
  1088. TexFmt[i].ddpfPixelFormat.dwLuminanceBitMask = 0x00FF;
  1089. TexFmt[i].ddpfPixelFormat.dwLuminanceAlphaBitMask = 0xFF00;
  1090. i++;
  1091. //@@BEGIN_DDKSPLIT
  1092. #if 0
  1093. // A8
  1094. ZeroMemory(&TexFmt[i].ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  1095. TexFmt[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  1096. TexFmt[i].ddpfPixelFormat.dwFourCC = 0;
  1097. TexFmt[i].ddpfPixelFormat.dwFlags = DDPF_ALPHA;
  1098. TexFmt[i].ddpfPixelFormat.dwAlphaBitDepth = 8;
  1099. TexFmt[i].ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF;
  1100. i++;
  1101. #endif
  1102. //@@END_DDKSPLIT
  1103. // L8
  1104. ZeroMemory(&TexFmt[i].ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  1105. TexFmt[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  1106. TexFmt[i].ddpfPixelFormat.dwFourCC = 0;
  1107. TexFmt[i].ddpfPixelFormat.dwFlags = DDPF_LUMINANCE;
  1108. TexFmt[i].ddpfPixelFormat.dwLuminanceBitCount = 8;
  1109. TexFmt[i].ddpfPixelFormat.dwLuminanceBitMask = 0xFF;
  1110. TexFmt[i].ddpfPixelFormat.dwLuminanceAlphaBitMask = 0;
  1111. i++;
  1112. #if DX7_PALETTETEXTURE
  1113. // P8
  1114. ZeroMemory(&TexFmt[i].ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  1115. TexFmt[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  1116. TexFmt[i].ddpfPixelFormat.dwFourCC = 0;
  1117. TexFmt[i].ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
  1118. TexFmt[i].ddpfPixelFormat.dwRGBBitCount = 8;
  1119. TexFmt[i].ddpfPixelFormat.dwRBitMask = 0x00000000;
  1120. TexFmt[i].ddpfPixelFormat.dwGBitMask = 0x00000000;
  1121. TexFmt[i].ddpfPixelFormat.dwBBitMask = 0x00000000;
  1122. TexFmt[i].ddpfPixelFormat.dwRGBAlphaBitMask = 0x00000000;
  1123. // Notice we aren't incrementing i for this format. This will effectively
  1124. // cause us to not report the palettized texture format in our DX7 caps
  1125. // list. This is intentional, and driver writers may choose to follow or
  1126. // not this approach. For our DX8 caps list we DO list paletted texture
  1127. // formats as supported. __SUR_bCheckTextureFormat is written to make
  1128. // sure we can create a paletted texture when asked for it.
  1129. // The whole reason behind this approach is because in legacy DX interfaces
  1130. // the TextureSwap method causes the surface and palette handle association
  1131. // to be lost. While there are some ugly and tricky ways around this (as in
  1132. // the Permedia2 sample driver), and there is no rational way to fix the
  1133. // problem.
  1134. #endif
  1135. // Return the number of texture formats to use
  1136. *pNumTextures = i;
  1137. } // __D3D_BuildTextureFormatsP3
  1138. #if DX8_DDI
  1139. //-----------------------------------------------------------------------------
  1140. //
  1141. // __D3D_Fill_DX8Caps
  1142. //
  1143. // Fills the D3DCAPS8 structure of a DX8 driver from legacy caps structures.
  1144. //
  1145. //-----------------------------------------------------------------------------
  1146. void
  1147. __D3D_Fill_DX8Caps(
  1148. D3DCAPS8 *pd3d8caps,
  1149. D3DDEVICEDESC_V1 *pDeviceDesc,
  1150. D3DHAL_D3DEXTENDEDCAPS *pD3DEC,
  1151. DDHALINFO *pDDHALInfo)
  1152. {
  1153. pd3d8caps->Caps = pDDHALInfo->ddCaps.dwCaps;
  1154. pd3d8caps->Caps2 = pDDHALInfo->ddCaps.dwCaps2;
  1155. pd3d8caps->DevCaps = pDeviceDesc->dwDevCaps;
  1156. pd3d8caps->PrimitiveMiscCaps = pDeviceDesc->dpcTriCaps.dwMiscCaps;
  1157. pd3d8caps->RasterCaps = pDeviceDesc->dpcTriCaps.dwRasterCaps;
  1158. pd3d8caps->ZCmpCaps = pDeviceDesc->dpcTriCaps.dwZCmpCaps;
  1159. pd3d8caps->SrcBlendCaps = pDeviceDesc->dpcTriCaps.dwSrcBlendCaps;
  1160. pd3d8caps->DestBlendCaps = pDeviceDesc->dpcTriCaps.dwDestBlendCaps;
  1161. pd3d8caps->AlphaCmpCaps = pDeviceDesc->dpcTriCaps.dwAlphaCmpCaps;
  1162. pd3d8caps->ShadeCaps = pDeviceDesc->dpcTriCaps.dwShadeCaps;
  1163. pd3d8caps->TextureCaps = pDeviceDesc->dpcTriCaps.dwTextureCaps;
  1164. pd3d8caps->TextureFilterCaps = pDeviceDesc->dpcTriCaps.dwTextureFilterCaps;
  1165. pd3d8caps->TextureAddressCaps= pDeviceDesc->dpcTriCaps.dwTextureAddressCaps;
  1166. pd3d8caps->MaxTextureWidth = pD3DEC->dwMaxTextureWidth;
  1167. pd3d8caps->MaxTextureHeight = pD3DEC->dwMaxTextureHeight;
  1168. pd3d8caps->MaxTextureRepeat = pD3DEC->dwMaxTextureRepeat;
  1169. pd3d8caps->MaxTextureAspectRatio = pD3DEC->dwMaxTextureAspectRatio;
  1170. pd3d8caps->MaxAnisotropy = pD3DEC->dwMaxAnisotropy;
  1171. pd3d8caps->MaxVertexW = pD3DEC->dvMaxVertexW;
  1172. pd3d8caps->GuardBandLeft = pD3DEC->dvGuardBandLeft;
  1173. pd3d8caps->GuardBandTop = pD3DEC->dvGuardBandTop;
  1174. pd3d8caps->GuardBandRight = pD3DEC->dvGuardBandRight;
  1175. pd3d8caps->GuardBandBottom = pD3DEC->dvGuardBandBottom;
  1176. pd3d8caps->ExtentsAdjust = pD3DEC->dvExtentsAdjust;
  1177. pd3d8caps->StencilCaps = pD3DEC->dwStencilCaps;
  1178. pd3d8caps->FVFCaps = pD3DEC->dwFVFCaps;
  1179. pd3d8caps->TextureOpCaps = pD3DEC->dwTextureOpCaps;
  1180. pd3d8caps->MaxTextureBlendStages = pD3DEC->wMaxTextureBlendStages;
  1181. pd3d8caps->MaxSimultaneousTextures = pD3DEC->wMaxSimultaneousTextures;
  1182. pd3d8caps->VertexProcessingCaps = pD3DEC->dwVertexProcessingCaps;
  1183. pd3d8caps->MaxActiveLights = pD3DEC->dwMaxActiveLights;
  1184. pd3d8caps->MaxUserClipPlanes = pD3DEC->wMaxUserClipPlanes;
  1185. pd3d8caps->MaxVertexBlendMatrices = pD3DEC->wMaxVertexBlendMatrices;
  1186. } // __D3D_Fill_DX8Caps
  1187. #endif // DX8_DDI