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.

488 lines
13 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: material.c
  6. * Content: Direct3D material management
  7. *@@BEGIN_MSINTERNAL
  8. *
  9. * History:
  10. * Date By Reason
  11. * ==== == ======
  12. * 11/12/95 stevela Initial rev with this header.
  13. *@@END_MSINTERNAL
  14. *
  15. ***************************************************************************/
  16. #include "pch.cpp"
  17. #pragma hdrstop
  18. /*
  19. * Create an api for the Direct3DMaterial object
  20. */
  21. #undef DPF_MODNAME
  22. #define DPF_MODNAME "Direct3DMaterial"
  23. HRESULT hookMaterialToD3D(LPDIRECT3DI lpD3DI,
  24. LPDIRECT3DMATERIALI lpD3DMatI)
  25. {
  26. LIST_INSERT_ROOT(&lpD3DI->materials, lpD3DMatI, list);
  27. lpD3DMatI->lpDirect3DI = lpD3DI;
  28. lpD3DI->numMaterials++;
  29. return (D3D_OK);
  30. }
  31. HRESULT hookMaterialToDevice(LPDIRECT3DMATERIALI lpMatI,
  32. LPDIRECT3DDEVICEI lpDevI,
  33. D3DMATERIALHANDLE hMat,
  34. DWORD hMatDDI)
  35. {
  36. LPD3DI_MATERIALBLOCK mBlock;
  37. if (D3DMalloc((void**)&mBlock, sizeof(D3DI_MATERIALBLOCK)) != D3D_OK) {
  38. D3D_ERR("failed to allocate space for material block");
  39. return (DDERR_OUTOFMEMORY);
  40. }
  41. mBlock->lpDevI = lpDevI;
  42. mBlock->lpD3DMaterialI = lpMatI;
  43. mBlock->hMat = hMat;
  44. mBlock->hMatDDI = hMatDDI;
  45. LIST_INSERT_ROOT(&lpMatI->blocks, mBlock, list);
  46. LIST_INSERT_ROOT(&lpDevI->matBlocks, mBlock, devList);
  47. return (D3D_OK);
  48. }
  49. void D3DI_RemoveMaterialBlock(LPD3DI_MATERIALBLOCK lpBlock)
  50. {
  51. // Remove from device
  52. if ( lpBlock->lpDevI )
  53. {
  54. D3DHAL_MaterialDestroy(lpBlock->lpDevI, lpBlock->hMat);
  55. }
  56. LIST_DELETE(lpBlock, devList);
  57. // Remove from material
  58. LIST_DELETE(lpBlock, list);
  59. D3DFree(lpBlock);
  60. }
  61. D3DMATERIALHANDLE findMaterialHandle(LPDIRECT3DMATERIALI lpMat,
  62. LPDIRECT3DDEVICEI lpDev)
  63. {
  64. LPD3DI_MATERIALBLOCK mBlock;
  65. D3DMATERIALHANDLE hMat = 0;
  66. mBlock = LIST_FIRST(&lpMat->blocks);
  67. while (mBlock) {
  68. if (!mBlock) {
  69. D3D_ERR("internal error - material list out of sync");
  70. return 0;
  71. }
  72. if (mBlock->lpDevI == lpDev) {
  73. hMat = mBlock->hMat;
  74. break;
  75. }
  76. mBlock = LIST_NEXT(mBlock,list);
  77. }
  78. return hMat;
  79. }
  80. HRESULT D3DAPI DIRECT3DMATERIALI::Initialize(LPDIRECT3D lpD3D)
  81. {
  82. return DDERR_ALREADYINITIALIZED;
  83. }
  84. /*
  85. * Create the Material
  86. */
  87. #undef DPF_MODNAME
  88. #define DPF_MODNAME "Direct3D::CreateMaterial"
  89. HRESULT D3DAPI DIRECT3DI::CreateMaterial(LPDIRECT3DMATERIAL* lplpD3DMat,
  90. IUnknown* pUnkOuter)
  91. {
  92. LPDIRECT3DMATERIAL3 lpD3DMat3;
  93. HRESULT ret = CreateMaterial(&lpD3DMat3, pUnkOuter);
  94. if (ret == D3D_OK)
  95. *lplpD3DMat = static_cast<LPDIRECT3DMATERIAL>(static_cast<LPDIRECT3DMATERIALI>(lpD3DMat3));
  96. return ret;
  97. }
  98. HRESULT D3DAPI DIRECT3DI::CreateMaterial(LPDIRECT3DMATERIAL2* lplpD3DMat,
  99. IUnknown* pUnkOuter)
  100. {
  101. LPDIRECT3DMATERIAL3 lpD3DMat3;
  102. HRESULT ret = CreateMaterial(&lpD3DMat3, pUnkOuter);
  103. if (ret == D3D_OK)
  104. *lplpD3DMat = static_cast<LPDIRECT3DMATERIAL2>(static_cast<LPDIRECT3DMATERIALI>(lpD3DMat3));
  105. return ret;
  106. }
  107. HRESULT D3DAPI DIRECT3DI::CreateMaterial(LPDIRECT3DMATERIAL3* lplpD3DMat,
  108. IUnknown* pUnkOuter)
  109. {
  110. LPDIRECT3DMATERIALI lpMat;
  111. HRESULT ret;
  112. if (pUnkOuter != NULL) {
  113. return CLASS_E_NOAGGREGATION;
  114. }
  115. ret = D3D_OK;
  116. CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
  117. /*
  118. * validate parms
  119. */
  120. if (!VALID_DIRECT3D3_PTR(this)) {
  121. D3D_ERR( "Invalid Direct3D pointer" );
  122. return DDERR_INVALIDOBJECT;
  123. }
  124. if (!VALID_OUTPTR(lplpD3DMat)) {
  125. D3D_ERR( "Invalid pointer to pointer" );
  126. return DDERR_INVALIDPARAMS;
  127. }
  128. *lplpD3DMat = NULL;
  129. lpMat = static_cast<LPDIRECT3DMATERIALI>(new DIRECT3DMATERIALI());
  130. if (!lpMat) {
  131. D3D_ERR("failed to allocate space for object");
  132. return (DDERR_OUTOFMEMORY);
  133. }
  134. /*
  135. * setup the object
  136. */
  137. /*
  138. * Put this device in the list of those owned by the
  139. * Direct3D object
  140. */
  141. ret = hookMaterialToD3D(this, lpMat);
  142. if (ret != D3D_OK) {
  143. D3D_ERR("failed to associate material with object");
  144. delete lpMat;
  145. return (ret);
  146. }
  147. *lplpD3DMat = (LPDIRECT3DMATERIAL3)lpMat;
  148. return (D3D_OK);
  149. }
  150. DIRECT3DMATERIALI::DIRECT3DMATERIALI()
  151. {
  152. memset(&dmMaterial, 0, sizeof(D3DMATERIAL)); /* Data describing material */
  153. dmMaterial.dwSize = sizeof(D3DMATERIAL);
  154. bRes= false; /* Is this material reserved in the driver */
  155. refCnt = 1;
  156. LIST_INITIALIZE(&blocks);
  157. }
  158. #undef DPF_MODNAME
  159. #define DPF_MODNAME "Direct3DMaterial::SetMaterial"
  160. HRESULT D3DAPI DIRECT3DMATERIALI::SetMaterial(LPD3DMATERIAL lpData)
  161. {
  162. HRESULT ret;
  163. HRESULT err;
  164. ret = D3D_OK;
  165. CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
  166. /*
  167. * validate parms
  168. */
  169. TRY
  170. {
  171. if (!VALID_DIRECT3DMATERIAL2_PTR(this)) {
  172. D3D_ERR( "Invalid Direct3DMaterial pointer" );
  173. return DDERR_INVALIDOBJECT;
  174. }
  175. if (!VALID_D3DMATERIAL_PTR(lpData)) {
  176. D3D_ERR( "Invalid D3DMATERIAL pointer" );
  177. return DDERR_INVALIDPARAMS;
  178. }
  179. }
  180. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  181. {
  182. D3D_ERR( "Exception encountered validating parameters" );
  183. return DDERR_INVALIDPARAMS;
  184. }
  185. if (memcmp(&this->dmMaterial, lpData, sizeof(D3DMATERIAL))) {
  186. LPD3DI_MATERIALBLOCK mBlock = LIST_FIRST(&this->blocks);
  187. this->dmMaterial = *lpData;
  188. /*
  189. * Download material data
  190. */
  191. while (mBlock) {
  192. err = D3DHAL_MaterialSetData(mBlock->lpDevI,
  193. mBlock->hMat, &this->dmMaterial);
  194. if ( err != DD_OK ) {
  195. D3D_ERR("error ocurred whilst informing device about material change");
  196. return err;
  197. }
  198. mBlock = LIST_NEXT(mBlock,list);
  199. }
  200. }
  201. return (ret);
  202. }
  203. #undef DPF_MODNAME
  204. #define DPF_MODNAME "Direct3DMaterial::GetMaterial"
  205. HRESULT D3DAPI DIRECT3DMATERIALI::GetMaterial(LPD3DMATERIAL lpData)
  206. {
  207. HRESULT ret;
  208. ret = D3D_OK;
  209. CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
  210. /*
  211. * validate parms
  212. */
  213. TRY
  214. {
  215. if (!VALID_DIRECT3DMATERIAL2_PTR(this)) {
  216. D3D_ERR( "Invalid Direct3DMaterial pointer" );
  217. return DDERR_INVALIDOBJECT;
  218. }
  219. if (!VALID_D3DMATERIAL_PTR(lpData)) {
  220. D3D_ERR( "Invalid D3DMATERIAL pointer" );
  221. return DDERR_INVALIDPARAMS;
  222. }
  223. }
  224. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  225. {
  226. D3D_ERR( "Exception encountered validating parameters" );
  227. return DDERR_INVALIDPARAMS;
  228. }
  229. *lpData = this->dmMaterial;
  230. return (ret);
  231. }
  232. #undef DPF_MODNAME
  233. #define DPF_MODNAME "Direct3DMaterial::GetHandle"
  234. HRESULT D3DAPI DIRECT3DMATERIALI::GetHandle(LPDIRECT3DDEVICE lpDev,
  235. LPD3DMATERIALHANDLE lphMat)
  236. {
  237. LPDIRECT3DDEVICE3 lpDev3 = static_cast<LPDIRECT3DDEVICE3>(static_cast<LPDIRECT3DDEVICEI>(lpDev));
  238. return GetHandle(lpDev3, lphMat);
  239. }
  240. HRESULT D3DAPI DIRECT3DMATERIALI::GetHandle(LPDIRECT3DDEVICE2 lpDev,
  241. LPD3DMATERIALHANDLE lphMat)
  242. {
  243. LPDIRECT3DDEVICE3 lpDev3 = static_cast<LPDIRECT3DDEVICE3>(static_cast<LPDIRECT3DDEVICEI>(lpDev));
  244. return GetHandle(lpDev3, lphMat);
  245. }
  246. HRESULT D3DAPI DIRECT3DMATERIALI::GetHandle(LPDIRECT3DDEVICE3 lpDev,
  247. LPD3DMATERIALHANDLE lphMat)
  248. {
  249. LPDIRECT3DDEVICEI lpD3DDevI;
  250. D3DMATERIALHANDLE hMat;
  251. HRESULT ret;
  252. HRESULT err;
  253. ret = D3D_OK;
  254. CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
  255. /*
  256. * validate parms
  257. */
  258. TRY
  259. {
  260. lpD3DDevI = static_cast<LPDIRECT3DDEVICEI>(lpDev);
  261. if (!VALID_DIRECT3DMATERIAL2_PTR(this)) {
  262. D3D_ERR( "Invalid Direct3DMaterial pointer" );
  263. return DDERR_INVALIDOBJECT;
  264. }
  265. if (!VALID_DIRECT3DDEVICE3_PTR(lpD3DDevI)) {
  266. D3D_ERR( "Invalid Direct3DDevice pointer" );
  267. return DDERR_INVALIDOBJECT;
  268. }
  269. if (!VALID_D3DMATERIALHANDLE_PTR(lphMat)) {
  270. D3D_ERR( "Invalid D3DMATERIALHANDLE pointer" );
  271. return DDERR_INVALIDPARAMS;
  272. }
  273. }
  274. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  275. {
  276. D3D_ERR( "Exception encountered validating parameters" );
  277. return DDERR_INVALIDPARAMS;
  278. }
  279. /*
  280. * If we're already on a device, return the right handle.
  281. */
  282. hMat = findMaterialHandle(this, lpD3DDevI);
  283. if (!hMat) {
  284. DWORD hMatDDI = 0x0;
  285. /*
  286. * Create the material handle through RLDDI
  287. */
  288. err = D3DHAL_MaterialCreate(lpD3DDevI, &hMat, &this->dmMaterial);
  289. if (err != DD_OK) {
  290. D3D_ERR("failed to allocate material through the device");
  291. return err;
  292. }
  293. err = hookMaterialToDevice(this, lpD3DDevI, hMat, hMatDDI);
  294. if (err != D3D_OK) {
  295. D3DHAL_MaterialDestroy(lpD3DDevI, hMat);
  296. D3D_ERR("failed to associated material to device");
  297. return err;
  298. }
  299. }
  300. *lphMat = hMat;
  301. return (ret);
  302. }
  303. #undef DPF_MODNAME
  304. #define DPF_MODNAME "Direct3DMaterial::Reserve"
  305. HRESULT D3DAPI DIRECT3DMATERIALI::Reserve()
  306. {
  307. #ifdef SUPPORT_RESERVE
  308. LPD3DI_MATERIALBLOCK mBlock, nBlock;
  309. #endif
  310. HRESULT ret;
  311. ret = D3D_OK;
  312. CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
  313. /*
  314. * validate parms
  315. */
  316. TRY
  317. {
  318. if (!VALID_DIRECT3DMATERIAL2_PTR(this)) {
  319. D3D_ERR( "Invalid Direct3DMaterial pointer" );
  320. return DDERR_INVALIDOBJECT;
  321. }
  322. }
  323. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  324. {
  325. D3D_ERR( "Exception encountered validating parameters" );
  326. return DDERR_INVALIDPARAMS;
  327. }
  328. #ifdef SUPPORT_RESERVE
  329. /*
  330. * Reserve the material through RLDDI
  331. */
  332. /*
  333. * Iterate over all devices we're associated with.
  334. */
  335. mBlock = LIST_FIRST(&this->blocks);
  336. while (mBlock) {
  337. if (RLDDIService(mBlock->lpDevI->stack, RLDDIMaterialReserve,
  338. mBlock->hMat, NULL) != DD_OK) {
  339. D3D_ERR("failed to reserve material");
  340. goto free_and_exit;
  341. }
  342. mBlock = LIST_NEXT(mBlock,list);
  343. }
  344. this->bRes = 1;
  345. return (ret);
  346. free_and_exit:
  347. nBlock = LIST_FIRST(&this->blocks);
  348. while (nBlock != mBlock) {
  349. if (!nBlock) {
  350. D3D_ERR("internal error - material blocks out of sync");
  351. return (DDERR_GENERIC);
  352. }
  353. ret = RLDDIService(nBlock->lpDevI->stack, RLDDIMaterialUnreserve,
  354. (LONG)nBlock->hMat, NULL);
  355. if (ret != D3D_OK) {
  356. D3D_ERR("error occured whilst unreserving material after error");
  357. }
  358. nBlock = LIST_NEXT(nBlock,list);
  359. }
  360. #else
  361. ret = DDERR_UNSUPPORTED;
  362. #endif
  363. return (ret);
  364. }
  365. #undef DPF_MODNAME
  366. #define DPF_MODNAME "Direct3DMaterial::Unreserve"
  367. HRESULT D3DAPI DIRECT3DMATERIALI::Unreserve()
  368. {
  369. #ifdef SUPPORT_RESERVE
  370. LPD3DI_MATERIALBLOCK mBlock;
  371. #endif
  372. HRESULT ret;
  373. ret = D3D_OK;
  374. CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
  375. /*
  376. * validate parms
  377. */
  378. TRY
  379. {
  380. if (!VALID_DIRECT3DMATERIAL2_PTR(this)) {
  381. D3D_ERR( "Invalid Direct3DMaterial pointer" );
  382. return DDERR_INVALIDOBJECT;
  383. }
  384. }
  385. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  386. {
  387. D3D_ERR( "Exception encountered validating parameters" );
  388. return DDERR_INVALIDPARAMS;
  389. }
  390. #ifdef SUPPORT_RESERVE
  391. /*
  392. * Unreserve the material through RLDDI
  393. */
  394. if (this->bRes) {
  395. mBlock = LIST_FIRST(&this->blocks);
  396. while (mBlock) {
  397. if (RLDDIService(mBlock->lpDevI->stack, RLDDIMaterialUnreserve,
  398. mBlock->hMat, NULL) != DD_OK) {
  399. D3D_ERR("failed to unreserve material");
  400. }
  401. mBlock = LIST_NEXT(mBlock,list);
  402. }
  403. }
  404. #else
  405. ret = DDERR_UNSUPPORTED;
  406. #endif
  407. return (ret);
  408. }