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.

865 lines
29 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: d3di.h
  6. * Content: Direct3D HAL include file
  7. *@@BEGIN_MSINTERNAL
  8. *
  9. * History:
  10. * Date By Reason
  11. * ==== == ======
  12. * 09/11/95 stevela Initial rev with this header.
  13. * 07/12/95 stevela Merged Colin's changes.
  14. * 10/12/95 stevela Removed AGGREGATE_D3D.
  15. * Validate args.
  16. * 17/04/96 colinmc Bug 17008: DirectDraw/Direct3D deadlock
  17. * 29/04/96 colinmc Bug 19954: Must query for Direct3D before texture
  18. * or device
  19. * 27/08/96 stevela Ifdefed out definition of ghEvent as we're using
  20. * DirectDraw's critical section.
  21. *@@END_MSINTERNAL
  22. *
  23. ***************************************************************************/
  24. #include "pch.cpp"
  25. #pragma hdrstop
  26. /*
  27. * Create an api for the Direct3D object
  28. */
  29. // Remove DDraw's type unsafe definition and replace with our C++ friendly def
  30. #ifdef VALIDEX_CODE_PTR
  31. #undef VALIDEX_CODE_PTR
  32. #endif
  33. #define VALIDEX_CODE_PTR( ptr ) \
  34. (!IsBadCodePtr( (FARPROC) ptr ) )
  35. LPCRITICAL_SECTION lpD3DCSect;
  36. #if DBG
  37. int iD3DCSCnt;
  38. #endif
  39. #if COLLECTSTATS
  40. void DIRECT3DI::ResetTexStats()
  41. {
  42. ((LPDDRAWI_DIRECTDRAW_INT)lpDD7)->lpLcl->dwNumTexLocks = ((LPDDRAWI_DIRECTDRAW_INT)lpDD7)->lpLcl->dwNumTexGetDCs = 0;
  43. m_setpris = m_setLODs = m_texCreates = m_texDestroys = 0;
  44. }
  45. void DIRECT3DI::GetTexStats(LPD3DDEVINFO_TEXTURING pStats)
  46. {
  47. pStats->dwNumSetPriorities = GetNumSetPris();
  48. pStats->dwNumSetLODs = GetNumSetLODs();
  49. pStats->dwNumCreates = GetNumTexCreates();
  50. pStats->dwNumDestroys = GetNumTexDestroys();
  51. pStats->dwNumLocks = GetNumTexLocks();
  52. pStats->dwNumGetDCs = GetNumTexGetDCs();
  53. }
  54. #endif
  55. //---------------------------------------------------------------------
  56. // for use by fns that take a GUID param before device is created
  57. BOOL IsValidD3DDeviceGuid(REFCLSID riid) {
  58. if (IsBadReadPtr(&riid, sizeof(CLSID))) {
  59. return FALSE;
  60. }
  61. if( IsEqualIID(riid, IID_IDirect3DRampDevice) ||
  62. IsEqualIID(riid, IID_IDirect3DRGBDevice) ||
  63. IsEqualIID(riid, IID_IDirect3DMMXDevice) ||
  64. IsEqualIID(riid, IID_IDirect3DHALDevice) ||
  65. IsEqualIID(riid, IID_IDirect3DRefDevice) ||
  66. IsEqualIID(riid, IID_IDirect3DNullDevice) ||
  67. IsEqualIID(riid, IID_IDirect3DTnLHalDevice)) {
  68. return TRUE;
  69. } else {
  70. return FALSE;
  71. }
  72. }
  73. //---------------------------------------------------------------------
  74. #undef DPF_MODNAME
  75. #define DPF_MODNAME "Direct3DCreate"
  76. DIRECT3DI::DIRECT3DI()
  77. {
  78. lpDD = NULL;
  79. lpDD7 = NULL;
  80. numDevs = 0;
  81. mD3DUnk.pD3DI = this;
  82. mD3DUnk.refCnt = 1;
  83. LIST_INITIALIZE(&devices);
  84. LIST_INITIALIZE(&textures);
  85. lpFreeList = NULL; /* nothing is allocated initially */
  86. lpBufferList = NULL;
  87. lpTextureManager = NULL;
  88. #ifdef __DISABLE_VIDMEM_VBS__
  89. bDisableVidMemVBs = FALSE;
  90. #endif
  91. }
  92. HRESULT DIRECT3DI::Initialize(IUnknown* pUnkOuter, LPDDRAWI_DIRECTDRAW_INT pDDrawInt)
  93. {
  94. // HACK. D3D needs a DD1 DDRAWI interface because it uses CreateSurface1 internally
  95. // for exebufs, among other things. Because pDDrawInt could be any DDRAWI type,
  96. // we need to QI to find a DD1 interface. But the D3DI object cannot keep a reference
  97. // to its parent DD object because it is aggegrated with the DD obj, so that would constitute
  98. // a circular reference that would prevent deletion. So we QI for DD1 interface, copy it into D3DI
  99. // and release it, then point lpDD at the copy. (disgusting)
  100. // another HACK alert: dont know which DDRAWI type pDDrawInt is, but a cast to LPDIRECTDRAW should
  101. // work because QI is in the same place in all the DDRAWI vtables and is the same fn for all
  102. HRESULT ret;
  103. ret = ((LPDIRECTDRAW)pDDrawInt)->QueryInterface(IID_IDirectDraw, (LPVOID*)&lpDD);
  104. if(FAILED(ret))
  105. {
  106. D3D_ERR( "QueryInterface for IDDraw failed" );
  107. return ret;
  108. }
  109. memcpy(&DDInt_DD1,lpDD,sizeof(DDInt_DD1));
  110. lpDD->Release();
  111. lpDD=(LPDIRECTDRAW)&DDInt_DD1;
  112. // We know that the pointer that is handed in is a DD7 interface, hence just typecast and assign
  113. lpDD7 = reinterpret_cast<LPDIRECTDRAW7>(pDDrawInt);
  114. lpTextureManager = new TextureCacheManager(this);
  115. if(lpTextureManager == 0)
  116. {
  117. D3D_ERR("Out of memory allocating texture manager");
  118. return E_OUTOFMEMORY;
  119. }
  120. ret = lpTextureManager->Initialize();
  121. if(ret != D3D_OK)
  122. {
  123. D3D_ERR("Failed to initialize texture manager");
  124. return ret;
  125. }
  126. #if COLLECTSTATS
  127. DWORD value = 0;
  128. GetD3DRegValue(REG_DWORD, "DisplayStats", &value, sizeof(DWORD));
  129. if(value != 0)
  130. {
  131. LOGFONT font;
  132. strcpy(font.lfFaceName, STATS_FONT_FACE);
  133. font.lfCharSet = DEFAULT_CHARSET;
  134. font.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  135. font.lfEscapement = 0;
  136. font.lfHeight = STATS_FONT_SIZE;
  137. font.lfItalic = FALSE;
  138. font.lfOrientation = 0;
  139. font.lfOutPrecision = OUT_DEFAULT_PRECIS;
  140. font.lfPitchAndFamily = DEFAULT_PITCH;
  141. font.lfQuality = DEFAULT_QUALITY;
  142. font.lfStrikeOut = FALSE;
  143. font.lfUnderline = FALSE;
  144. font.lfWeight = FW_DONTCARE;
  145. font.lfWidth = 0;
  146. m_hFont = CreateFontIndirect(&font);
  147. }
  148. else
  149. {
  150. m_hFont = 0;
  151. }
  152. #endif
  153. #ifdef __DISABLE_VIDMEM_VBS__
  154. {
  155. bDisableVidMemVBs = FALSE;
  156. DWORD value = 0;
  157. GetD3DRegValue(REG_DWORD, "DisableVidMemVBs", &value, sizeof(DWORD));
  158. if(value != 0)
  159. {
  160. // Disable VidMemVBs
  161. bDisableVidMemVBs = TRUE;
  162. }
  163. // We also disable vidmem VBs unless the driver explicitly asks us to turn them on...
  164. if (((LPDDRAWI_DIRECTDRAW_INT)lpDD7)->lpLcl->lpGbl->lpD3DGlobalDriverData)
  165. {
  166. if (0 == (((LPDDRAWI_DIRECTDRAW_INT)lpDD7)->lpLcl->lpGbl->lpD3DGlobalDriverData->hwCaps.dwDevCaps & D3DDEVCAPS_HWVERTEXBUFFER) )
  167. {
  168. bDisableVidMemVBs = TRUE;
  169. }
  170. }
  171. }
  172. #endif //__DISABLE_VIDMEM_VBS__
  173. /*
  174. * Are we really being aggregated?
  175. */
  176. if (pUnkOuter != NULL)
  177. {
  178. /*
  179. * Yup - we are being aggregated. Store the supplied
  180. * IUnknown so we can punt to that.
  181. * NOTE: We explicitly DO NOT AddRef here.
  182. */
  183. this->lpOwningIUnknown = pUnkOuter;
  184. /*
  185. * Store away the interface pointer
  186. */
  187. }
  188. else
  189. {
  190. /*
  191. * Nope - but we pretend we are anyway by storing our
  192. * own IUnknown as the parent IUnknown. This makes the
  193. * code much neater.
  194. */
  195. this->lpOwningIUnknown = static_cast<LPUNKNOWN>(&this->mD3DUnk);
  196. }
  197. return D3D_OK;
  198. }
  199. extern "C" HRESULT WINAPI Direct3DCreate(LPCRITICAL_SECTION lpDDCSect,
  200. LPUNKNOWN* lplpDirect3D,
  201. IUnknown* pUnkOuter)
  202. {
  203. LPDIRECT3DI pd3d;
  204. try
  205. {
  206. DPFINIT();
  207. /*
  208. * No need to validate params as DirectDraw is giving them to us.
  209. */
  210. /*
  211. * Is another thread coming in and is this the first time?
  212. */
  213. /*
  214. * We can let every invocation of this function assign
  215. * the critical section as we know its always going to
  216. * be the same value (for a D3D session).
  217. */
  218. lpD3DCSect = lpDDCSect;
  219. CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
  220. // Release in the destructor
  221. *lplpDirect3D = NULL;
  222. // We do not support non aggregated Direct3D object yet
  223. if (!pUnkOuter)
  224. return DDERR_INVALIDPARAMS;
  225. if (!(pd3d = static_cast<LPDIRECT3DI>(new DIRECT3DI)))
  226. {
  227. D3D_ERR("Out of memory allocating DIRECT3DI");
  228. return E_OUTOFMEMORY;
  229. }
  230. HRESULT hr = pd3d->Initialize(pUnkOuter, (LPDDRAWI_DIRECTDRAW_INT)pUnkOuter);
  231. if(hr != D3D_OK)
  232. {
  233. D3D_ERR("Failed to initialize Direct3D.");
  234. delete pd3d;
  235. return hr;
  236. }
  237. /*
  238. * NOTE: The special IUnknown is returned and not the actual
  239. * Direct3D interface so you can't use this to drive Direct3D.
  240. * You must query off this interface for the Direct3D interface.
  241. */
  242. *lplpDirect3D = static_cast<LPUNKNOWN>(&(pd3d->mD3DUnk));
  243. return (D3D_OK);
  244. }
  245. catch (HRESULT ret)
  246. {
  247. return ret;
  248. }
  249. }
  250. #undef DPF_MODNAME
  251. #define DPF_MODNAME "Direct3D::EnumDevices"
  252. extern BOOL isMMXprocessor(void);
  253. typedef struct _D3DI_DeviceType {
  254. CONST GUID *pGuid;
  255. char name[256];
  256. char description[512];
  257. } D3DI_DeviceType;
  258. // Static definitions for various enumerable devices
  259. static D3DI_DeviceType RGBDevice =
  260. {
  261. &IID_IDirect3DRGBDevice, "RGB Emulation",
  262. "Microsoft Direct3D RGB Software Emulation"
  263. };
  264. static D3DI_DeviceType HALDevice =
  265. {
  266. &IID_IDirect3DHALDevice, "Direct3D HAL",
  267. "Microsoft Direct3D Hardware acceleration through Direct3D HAL"
  268. };
  269. static D3DI_DeviceType RefDevice =
  270. {
  271. &IID_IDirect3DRefDevice, "Reference Rasterizer",
  272. "Microsoft Reference Rasterizer"
  273. };
  274. static D3DI_DeviceType NullDevice =
  275. {
  276. &IID_IDirect3DNullDevice, "Null device",
  277. "Microsoft Null Device"
  278. };
  279. static D3DI_DeviceType TnLHALDevice =
  280. {
  281. &IID_IDirect3DTnLHalDevice, "Direct3D T&L HAL",
  282. "Microsoft Direct3D Hardware Transform and Lighting acceleration capable device"
  283. };
  284. static D3DI_DeviceType *AllDevices[] =
  285. {
  286. &RGBDevice, &HALDevice, &RefDevice, &NullDevice,
  287. &TnLHALDevice, NULL
  288. };
  289. HRESULT
  290. DIRECT3DI::EnumDevices(LPD3DENUMDEVICESCALLBACK7 lpEnumCallback,
  291. LPVOID lpContext, DWORD dwSize, DWORD dwVer)
  292. {
  293. HRESULT err, userRet;
  294. HKEY hKey;
  295. LONG result;
  296. int i;
  297. try
  298. {
  299. CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
  300. // Release in the destructor
  301. if (!VALIDEX_CODE_PTR((FARPROC)lpEnumCallback))
  302. {
  303. D3D_ERR( "Invalid callback pointer" );
  304. return DDERR_INVALIDPARAMS;
  305. }
  306. BOOL bSoftwareOnly = FALSE;
  307. BOOL bEnumReference = FALSE;
  308. BOOL bEnumNullDevice = FALSE;
  309. BOOL bEnumSeparateMMX = FALSE;
  310. result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RESPATH, 0, KEY_READ, &hKey);
  311. if (result == ERROR_SUCCESS)
  312. {
  313. DWORD dwData, dwType;
  314. DWORD dwDataSize;
  315. // Enumerate software rasterizers only ?
  316. dwDataSize = sizeof(dwData);
  317. result = RegQueryValueEx(hKey, "SoftwareOnly", NULL,
  318. &dwType, (BYTE *) &dwData, &dwDataSize);
  319. if ( result == ERROR_SUCCESS && dwType == REG_DWORD )
  320. {
  321. bSoftwareOnly = ( dwData != 0 );
  322. }
  323. // Enumerate Reference Rasterizer ?
  324. dwDataSize = sizeof(dwData);
  325. result = RegQueryValueEx(hKey, "EnumReference", NULL,
  326. &dwType, (BYTE *)&dwData, &dwDataSize);
  327. if (result == ERROR_SUCCESS &&
  328. dwType == REG_DWORD &&
  329. dwDataSize == sizeof(dwData))
  330. {
  331. bEnumReference = (BOOL)dwData;
  332. }
  333. // Enumerate Null Device ?
  334. dwDataSize = sizeof(dwData);
  335. result = RegQueryValueEx(hKey, "EnumNullDevice", NULL,
  336. &dwType, (BYTE *)&dwData, &dwDataSize);
  337. if (result == ERROR_SUCCESS &&
  338. dwType == REG_DWORD &&
  339. dwDataSize == sizeof(dwData))
  340. {
  341. bEnumNullDevice = (BOOL)dwData;
  342. }
  343. RegCloseKey( hKey );
  344. }
  345. D3DI_DeviceType **lpDevices = AllDevices;
  346. userRet = D3DENUMRET_OK;
  347. for (i = 0; lpDevices[i] && userRet == D3DENUMRET_OK; i++)
  348. {
  349. LPSTR drvName = lpDevices[i]->name;
  350. LPSTR drvDesc = lpDevices[i]->description;
  351. REFCLSID riid = *lpDevices[i]->pGuid;
  352. D3DDEVICEDESC7 HWDesc;
  353. D3DDEVICEDESC7 HELDesc;
  354. LPDDRAWI_DIRECTDRAW_GBL lpDDGbl;
  355. IHalProvider *pHalProv;
  356. HINSTANCE hDll;
  357. if ( !bEnumReference &&
  358. IsEqualIID(riid, IID_IDirect3DRefDevice))
  359. {
  360. // Not enumerating the reference.
  361. continue;
  362. }
  363. if (!bEnumNullDevice &&
  364. IsEqualIID(riid, IID_IDirect3DNullDevice))
  365. {
  366. // Not enumerating the Null device.
  367. continue;
  368. }
  369. // By COM definition, our owning IUnknown is a pointer to the
  370. // DirectDraw object that was used to create us.
  371. // Check this for the existence of a Direct3D HAL.
  372. lpDDGbl = ((LPDDRAWI_DIRECTDRAW_INT)this->lpDD)->lpLcl->lpGbl;
  373. if (IsEqualIID(riid, IID_IDirect3DTnLHalDevice) && (lpDDGbl->lpD3DGlobalDriverData))
  374. {
  375. if (!(lpDDGbl->lpD3DGlobalDriverData->hwCaps.dwDevCaps &
  376. D3DDEVCAPS_HWTRANSFORMANDLIGHT))
  377. {
  378. // Not enumerating the T&L device if the hardware doesnt support
  379. // T&L
  380. continue;
  381. }
  382. }
  383. // See if this is a software driver.
  384. err = GetSwHalProvider(riid, &pHalProv, &hDll);
  385. if (err == S_OK)
  386. {
  387. // Successfully got a software driver.
  388. }
  389. else if (err == E_NOINTERFACE &&
  390. ! bSoftwareOnly &&
  391. GetHwHalProvider(riid, &pHalProv, &hDll, lpDDGbl) == S_OK)
  392. {
  393. // Successfully got a hardware driver.
  394. }
  395. else
  396. {
  397. // Unrecognized driver.
  398. continue;
  399. }
  400. err = pHalProv->GetCaps(lpDDGbl, &HWDesc, &HELDesc, dwVer);
  401. pHalProv->Release();
  402. if (hDll != NULL)
  403. {
  404. FreeLibrary(hDll);
  405. }
  406. if (err != S_OK)
  407. {
  408. continue;
  409. }
  410. if( HWDesc.wMaxVertexBlendMatrices == 1 )
  411. HWDesc.wMaxVertexBlendMatrices = 0;
  412. if( HELDesc.wMaxVertexBlendMatrices == 1 )
  413. HELDesc.wMaxVertexBlendMatrices = 0;
  414. // If Hal device is being enumerated, strip out the
  415. // HWTRANSFORM... flag
  416. if (IsEqualIID(riid, IID_IDirect3DHALDevice))
  417. {
  418. HWDesc.dwMaxActiveLights = 0xffffffff;
  419. HWDesc.wMaxVertexBlendMatrices = 4;
  420. HWDesc.wMaxUserClipPlanes = __MAXUSERCLIPPLANES;
  421. HWDesc.dwVertexProcessingCaps = D3DVTXPCAPS_ALL;
  422. HWDesc.dwDevCaps &= ~(D3DDEVCAPS_HWTRANSFORMANDLIGHT);
  423. }
  424. if (IsEqualIID(riid, IID_IDirect3DRGBDevice))
  425. {
  426. HELDesc.dwMaxActiveLights = 0xffffffff;
  427. HELDesc.wMaxVertexBlendMatrices = 4;
  428. HELDesc.wMaxUserClipPlanes = __MAXUSERCLIPPLANES;
  429. HELDesc.dwVertexProcessingCaps = D3DVTXPCAPS_ALL;
  430. }
  431. if (IsEqualIID(riid, IID_IDirect3DHALDevice) || IsEqualIID(riid, IID_IDirect3DTnLHalDevice))
  432. {
  433. memcpy(&HWDesc.deviceGUID, lpDevices[i]->pGuid, sizeof(GUID));
  434. userRet = (*lpEnumCallback)(drvDesc, drvName,
  435. &HWDesc, lpContext);
  436. }
  437. else
  438. {
  439. memcpy(&HELDesc.deviceGUID, lpDevices[i]->pGuid, sizeof(GUID));
  440. userRet = (*lpEnumCallback)(drvDesc, drvName,
  441. &HELDesc, lpContext);
  442. }
  443. }
  444. return D3D_OK;
  445. }
  446. catch (HRESULT ret)
  447. {
  448. return ret;
  449. }
  450. }
  451. HRESULT D3DAPI DIRECT3DI::EnumDevices(LPD3DENUMDEVICESCALLBACK7 lpEnumCallback,
  452. LPVOID lpContext)
  453. {
  454. return EnumDevices(lpEnumCallback, lpContext, D3DDEVICEDESC7SIZE, 4);
  455. }
  456. #undef DPF_MODNAME
  457. #define DPF_MODNAME "Direct3DI::EnumZBufferFormats"
  458. HRESULT D3DAPI DIRECT3DI::EnumZBufferFormats(REFCLSID riid,
  459. LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
  460. LPVOID lpContext)
  461. {
  462. HRESULT ret, userRet;
  463. LPDDPIXELFORMAT lpTmpPixFmts;
  464. DWORD i,cPixFmts;
  465. try
  466. {
  467. CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
  468. ret = D3D_OK;
  469. if (!VALID_DIRECT3D_PTR(this))
  470. {
  471. D3D_ERR( "Invalid Direct3D3 pointer" );
  472. return DDERR_INVALIDOBJECT;
  473. }
  474. if (!VALIDEX_CODE_PTR(lpEnumCallback))
  475. {
  476. D3D_ERR( "Invalid callback pointer" );
  477. return DDERR_INVALIDPARAMS;
  478. }
  479. if(!IsValidD3DDeviceGuid(riid))
  480. {
  481. D3D_ERR( "Invalid D3D Device GUID" );
  482. return DDERR_INVALIDPARAMS;
  483. }
  484. if( IsEqualIID(riid, IID_IDirect3DHALDevice) ||
  485. IsEqualIID(riid, IID_IDirect3DTnLHalDevice) )
  486. {
  487. LPDDRAWI_DIRECTDRAW_GBL pDdGbl=((LPDDRAWI_DIRECTDRAW_INT)this->lpDD)->lpLcl->lpGbl;
  488. LPD3DHAL_GLOBALDRIVERDATA lpD3DHALGlobalDriverData=pDdGbl->lpD3DGlobalDriverData;
  489. DWORD dwHW_ZBitDepthFlags;
  490. if (NULL == lpD3DHALGlobalDriverData)
  491. {
  492. D3D_ERR("No HAL Support ZBufferBitDepths!");
  493. return (DDERR_NOZBUFFERHW);
  494. }
  495. cPixFmts=pDdGbl->dwNumZPixelFormats;
  496. if (cPixFmts==0) {
  497. // driver is pre-dx6, so it doesn't support stencil buffer pix fmts or this callback.
  498. // we can fake support using DD_BD bits in dwZBufferBitDepth in D3DDEVICEDESC
  499. D3D_WARN(6,"EnumZBufferFormats not supported directly by driver, faking it using dwDeviceZBufferBitDepth DD_BD bits");
  500. dwHW_ZBitDepthFlags=lpD3DHALGlobalDriverData->hwCaps.dwDeviceZBufferBitDepth;
  501. if(!(dwHW_ZBitDepthFlags & (DDBD_8|DDBD_16|DDBD_24|DDBD_32))) {
  502. D3D_ERR("No Supported ZBufferBitDepths!");
  503. return (DDERR_NOZBUFFERHW);
  504. }
  505. // malloc space for 4 DDPIXELFORMATs, since that the most there could be (DDBD_8,16,24,32)
  506. if (D3DMalloc((void**)&lpTmpPixFmts, 4*sizeof(DDPIXELFORMAT)) != D3D_OK) {
  507. D3D_ERR("failed to alloc space for return descriptions");
  508. return (DDERR_OUTOFMEMORY);
  509. }
  510. DWORD zdepthflags[4]= {DDBD_8,DDBD_16,DDBD_24,DDBD_32};
  511. DWORD zbitdepths[4]= {8,16,24,32};
  512. DWORD zbitmasks[4]= {0xff,0xffff,0xffffff,0xffffffff};
  513. memset(lpTmpPixFmts,0,sizeof(4*sizeof(DDPIXELFORMAT)));
  514. // create some DDPIXELFORMATs the app can look at
  515. for(i=0;i<4;i++) {
  516. if(dwHW_ZBitDepthFlags & zdepthflags[i]) {
  517. lpTmpPixFmts[cPixFmts].dwSize=sizeof(DDPIXELFORMAT);
  518. lpTmpPixFmts[cPixFmts].dwFlags=DDPF_ZBUFFER;
  519. lpTmpPixFmts[cPixFmts].dwZBufferBitDepth=zbitdepths[i];
  520. lpTmpPixFmts[cPixFmts].dwZBitMask= zbitmasks[i];
  521. cPixFmts++;
  522. }
  523. }
  524. } else {
  525. // only show the app a temp copy of DDraw's real records
  526. if (D3DMalloc((void**)&lpTmpPixFmts, cPixFmts*sizeof(DDPIXELFORMAT)) != D3D_OK) {
  527. D3D_ERR("Out of memory allocating space for return descriptions");
  528. return (DDERR_OUTOFMEMORY);
  529. }
  530. memcpy(lpTmpPixFmts, pDdGbl->lpZPixelFormats, cPixFmts*sizeof(DDPIXELFORMAT));
  531. }
  532. } else {
  533. // Handle SW rasterizers
  534. DDPIXELFORMAT *pDDPF;
  535. // malloc space for 10 DDPIXELFORMAT's, which is currently more than enough for the SW rasterizers
  536. if (D3DMalloc((void**)&lpTmpPixFmts, 10*sizeof(DDPIXELFORMAT)) != D3D_OK) {
  537. D3D_ERR("Out of memory allocating space for return descriptions");
  538. return (DDERR_OUTOFMEMORY);
  539. }
  540. cPixFmts=GetSwZBufferFormats(riid,&pDDPF);
  541. memcpy(lpTmpPixFmts, pDDPF, cPixFmts*sizeof(DDPIXELFORMAT));
  542. }
  543. userRet = D3DENUMRET_OK;
  544. for (i = 0; (i < cPixFmts) && (userRet == D3DENUMRET_OK); i++) {
  545. userRet = (*lpEnumCallback)(&lpTmpPixFmts[i], lpContext);
  546. }
  547. D3DFree(lpTmpPixFmts);
  548. return (D3D_OK);
  549. }
  550. catch (HRESULT ret)
  551. {
  552. return ret;
  553. }
  554. }
  555. #undef DPF_MODNAME
  556. #define DPF_MODNAME "DIRECT3D::EvictManagedTextures"
  557. HRESULT D3DAPI
  558. DIRECT3DI::EvictManagedTextures()
  559. {
  560. try
  561. {
  562. CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
  563. if (!VALID_DIRECT3D_PTR(this))
  564. {
  565. D3D_ERR( "Invalid Direct3D3 pointer" );
  566. return DDERR_INVALIDOBJECT;
  567. }
  568. LPDIRECT3DDEVICEI lpDevI = LIST_FIRST(&this->devices);
  569. while (lpDevI)
  570. {
  571. if (lpDevI->dwFEFlags & D3DFE_REALHAL)
  572. {
  573. if (DDCAPS2_CANMANAGETEXTURE &
  574. ((LPDDRAWI_DIRECTDRAW_INT)this->lpDD)->lpLcl->lpGbl->ddCaps.dwCaps2)
  575. {
  576. lpDevI->SetRenderStateI((D3DRENDERSTATETYPE)D3DRENDERSTATE_EVICTMANAGEDTEXTURES,1);
  577. lpDevI->FlushStates();
  578. }
  579. lpTextureManager->EvictTextures();
  580. break;
  581. }
  582. lpDevI = LIST_NEXT(lpDevI,list);
  583. }
  584. return D3D_OK;
  585. }
  586. catch (HRESULT ret)
  587. {
  588. return ret;
  589. }
  590. }
  591. #undef DPF_MODNAME
  592. #define DPF_MODNAME "DIRECT3D::FlushDevicesExcept"
  593. HRESULT DIRECT3DI::FlushDevicesExcept(LPDIRECT3DDEVICEI pDev)
  594. {
  595. LPDIRECT3DDEVICEI lpDevI = LIST_FIRST(&this->devices);
  596. while (lpDevI)
  597. {
  598. if(lpDevI != pDev)
  599. {
  600. HRESULT hr = lpDevI->FlushStates();
  601. if(hr != D3D_OK)
  602. {
  603. DPF_ERR("Error flushing device in FlushDevicesExcept");
  604. return hr;
  605. }
  606. }
  607. lpDevI = LIST_NEXT(lpDevI,list);
  608. }
  609. return D3D_OK;
  610. }
  611. #undef DPF_MODNAME
  612. #define DPF_MODNAME "FlushD3DDevices"
  613. extern "C" HRESULT WINAPI FlushD3DDevices(LPDDRAWI_DDRAWSURFACE_LCL surf_lcl)
  614. {
  615. try
  616. {
  617. ULONGLONG qwBatch = (surf_lcl->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_CUBEMAP)
  618. && (surf_lcl->lpAttachListFrom != NULL) ?
  619. surf_lcl->lpAttachListFrom->lpAttached->lpSurfMore->qwBatch.QuadPart :
  620. surf_lcl->lpSurfMore->qwBatch.QuadPart;
  621. LPDIRECT3DI lpD3D = static_cast<CDirect3DUnk*>(surf_lcl->lpSurfMore->lpDD_lcl->pD3DIUnknown)->pD3DI;
  622. DDASSERT(lpD3D);
  623. LPDIRECT3DDEVICEI lpDevI = LIST_FIRST(&lpD3D->devices);
  624. while (lpDevI)
  625. {
  626. if(lpDevI->m_qwBatch <= qwBatch)
  627. {
  628. HRESULT hr = lpDevI->FlushStates();
  629. if(hr != D3D_OK)
  630. {
  631. DPF_ERR("Error flushing device in FlushD3DDevices");
  632. return hr;
  633. }
  634. }
  635. lpDevI = LIST_NEXT(lpDevI,list);
  636. }
  637. return DD_OK;
  638. }
  639. catch (HRESULT ret)
  640. {
  641. return ret;
  642. }
  643. }
  644. extern "C" void WINAPI PaletteUpdateNotify(
  645. LPVOID pD3DIUnknown,
  646. DWORD dwPaletteHandle,
  647. DWORD dwStartIndex,
  648. DWORD dwNumberOfIndices,
  649. LPPALETTEENTRY pFirstIndex)
  650. {
  651. try
  652. {
  653. LPDIRECT3DI lpD3D = static_cast<CDirect3DUnk*>(pD3DIUnknown)->pD3DI;
  654. DDASSERT(lpD3D);
  655. LPDIRECT3DDEVICEI lpDevI = LIST_FIRST(&lpD3D->devices);
  656. while (lpDevI)
  657. {
  658. D3D_INFO(4,"PaletteUpdateNotify lpDevI(%x) %08lx %08lx %08lx %08lx",
  659. lpDevI,dwPaletteHandle,dwStartIndex,dwNumberOfIndices,*(DWORD*)&pFirstIndex[10]);
  660. if (IS_DX7HAL_DEVICE(lpDevI) &&
  661. (lpDevI->dwFEFlags & D3DFE_REALHAL)
  662. )
  663. {
  664. if(lpD3D->numDevs > 1)
  665. lpD3D->FlushDevicesExcept(lpDevI);
  666. static_cast<CDirect3DDevice7*>(lpDevI)->UpdatePalette(dwPaletteHandle,dwStartIndex,dwNumberOfIndices,pFirstIndex);
  667. if(lpD3D->numDevs > 1)
  668. lpDevI->FlushStates();
  669. break;
  670. }
  671. lpDevI = LIST_NEXT(lpDevI,list);
  672. }
  673. }
  674. catch (HRESULT ret)
  675. {
  676. D3D_ERR("PaletteUpdateNotify: FlushStates failed");
  677. }
  678. }
  679. extern "C" void WINAPI PaletteAssociateNotify(
  680. LPVOID pD3DIUnknown,
  681. DWORD dwPaletteHandle,
  682. DWORD dwPaletteFlags,
  683. LPDDRAWI_DDRAWSURFACE_LCL surf_lcl )
  684. {
  685. try
  686. {
  687. LPDIRECT3DI lpD3D = static_cast<CDirect3DUnk*>(pD3DIUnknown)->pD3DI;
  688. DDASSERT(lpD3D);
  689. LPDIRECT3DDEVICEI lpDevI = LIST_FIRST(&lpD3D->devices);
  690. while (lpDevI)
  691. {
  692. D3D_INFO(4,"PaletteAssociateNotify lpDevI(%x) %08lx %08lx",
  693. lpDevI,dwPaletteHandle,surf_lcl->lpSurfMore->dwSurfaceHandle);
  694. if (IS_DX7HAL_DEVICE(lpDevI) &&
  695. (lpDevI->dwFEFlags & D3DFE_REALHAL)
  696. )
  697. {
  698. if(lpD3D->numDevs > 1)
  699. lpD3D->FlushDevicesExcept(lpDevI);
  700. static_cast<CDirect3DDevice7*>(lpDevI)->SetPalette(dwPaletteHandle,dwPaletteFlags,surf_lcl->lpSurfMore->dwSurfaceHandle);
  701. lpDevI->BatchTexture(surf_lcl);
  702. if(lpD3D->numDevs > 1)
  703. lpDevI->FlushStates();
  704. break;
  705. }
  706. lpDevI = LIST_NEXT(lpDevI,list);
  707. }
  708. }
  709. catch (HRESULT ret)
  710. {
  711. D3D_ERR("PaletteAssociateNotify: FlushStates failed");
  712. }
  713. }
  714. extern "C" void WINAPI SurfaceFlipNotify(LPVOID pD3DIUnknown)
  715. {
  716. LPDIRECT3DI lpD3D = static_cast<CDirect3DUnk*>(pD3DIUnknown)->pD3DI;
  717. DDASSERT(lpD3D);
  718. LPDIRECT3DDEVICEI lpDevI = LIST_FIRST(&lpD3D->devices);
  719. D3D_INFO(4,"SurfaceFlipNotify");
  720. while (lpDevI)
  721. {
  722. if (IS_DX7HAL_DEVICE(lpDevI))
  723. {
  724. try
  725. {
  726. CDirect3DDevice7* lpDevI7 = static_cast<CDirect3DDevice7*>(lpDevI);
  727. #ifndef WIN95
  728. if(lpDevI->hSurfaceTarget != ((LPDDRAWI_DDRAWSURFACE_INT)lpDevI->lpDDSTarget)->lpLcl->hDDSurface)
  729. {
  730. lpDevI7->SetRenderTargetINoFlush(lpDevI->lpDDSTarget,lpDevI->lpDDSZBuffer);
  731. lpDevI->hSurfaceTarget=((LPDDRAWI_DDRAWSURFACE_INT)lpDevI->lpDDSTarget)->lpLcl->hDDSurface;
  732. }
  733. #else
  734. if(lpDevI->hSurfaceTarget != ((LPDDRAWI_DDRAWSURFACE_INT)lpDevI->lpDDSTarget)->lpLcl->lpSurfMore->dwSurfaceHandle)
  735. {
  736. lpDevI7->SetRenderTargetINoFlush(lpDevI->lpDDSTarget,lpDevI->lpDDSZBuffer);
  737. lpDevI->hSurfaceTarget=((LPDDRAWI_DDRAWSURFACE_INT)lpDevI->lpDDSTarget)->lpLcl->lpSurfMore->dwSurfaceHandle;
  738. }
  739. #endif
  740. }
  741. catch (HRESULT ret)
  742. {
  743. D3D_ERR("SetRenderTarget Failed on SurfaceFlipNotify!");
  744. }
  745. }
  746. lpDevI = LIST_NEXT(lpDevI,list);
  747. }
  748. }
  749. #undef DPF_MODNAME
  750. #define DPF_MODNAME "D3DTextureUpdate"
  751. extern "C" void WINAPI D3DTextureUpdate(IUnknown FAR * pD3DIUnknown)
  752. {
  753. LPDIRECT3DI lpD3D = static_cast<CDirect3DUnk*>(pD3DIUnknown)->pD3DI;
  754. DDASSERT(lpD3D);
  755. LPDIRECT3DDEVICEI lpDevI = LIST_FIRST(&lpD3D->devices);
  756. while (lpDevI)
  757. {
  758. lpDevI->dwFEFlags |= D3DFE_NEED_TEXTURE_UPDATE;
  759. lpDevI = LIST_NEXT(lpDevI,list);
  760. }
  761. }
  762. #undef DPF_MODNAME
  763. #define DPF_MODNAME "D3DTextureUpdate"
  764. extern "C" void WINAPI D3DBreakVBLock(LPVOID lpVB)
  765. {
  766. DDASSERT(lpVB);
  767. CDirect3DVertexBuffer* lpVBI = static_cast<CDirect3DVertexBuffer*>(lpVB);
  768. lpVBI->BreakLock();
  769. }