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.

1058 lines
38 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: tldevice.cpp
  6. *
  7. * Content: Support code for device with transformation and lighting
  8. *
  9. ***************************************************************************/
  10. #include "pch.cpp"
  11. #pragma hdrstop
  12. #include "tlhal.h"
  13. #include "drawprim.hpp"
  14. #include "pvvid.h"
  15. //=====================================================================
  16. //
  17. // CDirect3DDevice7 interface
  18. //
  19. //=====================================================================
  20. #undef DPF_MODNAME
  21. #define DPF_MODNAME "CDirect3DDevice7::Init"
  22. HRESULT CDirect3DDevice7::Init(
  23. REFCLSID riid, LPDIRECT3DI lpD3DI, LPDIRECTDRAWSURFACE lpDDS,
  24. IUnknown* pUnkOuter, LPUNKNOWN* lplpD3DDevice)
  25. {
  26. #if 0
  27. // Stateblocks are always emulated on DX7
  28. DWORD value = 0;
  29. GetD3DRegValue(REG_DWORD, "EmulateStateBlocks", &value, sizeof(DWORD));
  30. if(value == 0)
  31. {
  32. // All DX7 devices should support state sets
  33. this->dwFEFlags |= D3DFE_STATESETS;
  34. }
  35. #endif
  36. HRESULT ret = CDirect3DDeviceIDP2::Init(riid, lpD3DI, lpDDS, pUnkOuter, lplpD3DDevice);
  37. if (ret != D3D_OK)
  38. return ret;
  39. // Do device specific initialization here
  40. return D3D_OK;
  41. }
  42. //---------------------------------------------------------------------
  43. //
  44. #undef DPF_MODNAME
  45. #define DPF_MODNAME "CDirect3DDevice7::WriteStateSetToDevice"
  46. void CDirect3DDevice7::WriteStateSetToDevice(D3DSTATEBLOCKTYPE sbt)
  47. {
  48. DWORD dwDeviceHandle;
  49. LPVOID pBuffer;
  50. DWORD dwBufferSize;
  51. m_pStateSets->GetDeviceBufferInfo(&dwDeviceHandle, &pBuffer, &dwBufferSize);
  52. // If device buffer is empty we do not create the set state macro in the device
  53. if (dwBufferSize == 0)
  54. return;
  55. DWORD dwByteCount = dwBufferSize + (sizeof(D3DHAL_DP2STATESET) + sizeof(D3DHAL_DP2COMMAND)) * 2;
  56. // Check to see if there is space to add a new command for space
  57. if (dwByteCount + dwDP2CommandLength > dwDP2CommandBufSize)
  58. {
  59. // Request the driver to grow the command buffer upon flush
  60. dp2data.dwReqCommandBufSize = dwByteCount;
  61. dp2data.dwFlags |= D3DHALDP2_REQCOMMANDBUFSIZE;
  62. HRESULT ret = FlushStates();
  63. dp2data.dwFlags &= ~D3DHALDP2_REQCOMMANDBUFSIZE;
  64. if (ret != D3D_OK)
  65. throw ret;
  66. // Check if the driver did give us what we need or do it ourselves
  67. ret = GrowCommandBuffer(this->lpDirect3DI, dwByteCount);
  68. if (ret != D3D_OK)
  69. {
  70. D3D_ERR("Could not grow Command Buffer");
  71. throw ret;
  72. }
  73. }
  74. lpDP2CurrCommand = (LPD3DHAL_DP2COMMAND)((LPBYTE)lpvDP2Commands +
  75. dwDP2CommandLength + dp2data.dwCommandOffset);
  76. lpDP2CurrCommand->bCommand = D3DDP2OP_STATESET;
  77. lpDP2CurrCommand->bReserved = 0;
  78. lpDP2CurrCommand->wStateCount = 1;
  79. LPD3DHAL_DP2STATESET pData = (LPD3DHAL_DP2STATESET)(lpDP2CurrCommand + 1);
  80. pData->dwOperation = D3DHAL_STATESETBEGIN;
  81. pData->dwParam = dwDeviceHandle;
  82. pData->sbType = sbt;
  83. D3D_INFO(6, "Write Ins:%08lx", *(LPDWORD)lpDP2CurrCommand);
  84. // Copy the entire state macro to the DP2 buffer
  85. memcpy(pData + 1, pBuffer, dwBufferSize);
  86. lpDP2CurrCommand = (LPD3DHAL_DP2COMMAND)((LPBYTE)(pData + 1) + dwBufferSize);
  87. lpDP2CurrCommand->bCommand = D3DDP2OP_STATESET;
  88. lpDP2CurrCommand->bReserved = 0;
  89. lpDP2CurrCommand->wStateCount = 1;
  90. pData = (LPD3DHAL_DP2STATESET)(lpDP2CurrCommand + 1);
  91. pData->dwOperation = D3DHAL_STATESETEND;
  92. pData->dwParam = dwDeviceHandle;
  93. pData->sbType = sbt;
  94. D3D_INFO(6, "Write Ins:%08lx", *(LPDWORD)lpDP2CurrCommand);
  95. dwDP2CommandLength += dwByteCount;
  96. HRESULT ret = FlushStates();
  97. if (ret != D3D_OK)
  98. {
  99. D3D_ERR("Error trying to render batched commands in WriteStateSetToDevice");
  100. throw ret;
  101. }
  102. else
  103. {
  104. if(this->dwFEFlags & D3DFE_LOSTSURFACES)
  105. {
  106. D3D_ERR("State blocks lost in WriteStateSetToDevice");
  107. throw DDERR_SURFACELOST;
  108. }
  109. }
  110. }
  111. //---------------------------------------------------------------------
  112. //
  113. #undef DPF_MODNAME
  114. #define DPF_MODNAME "CDirect3DDevice7::TexBltI"
  115. HRESULT CDirect3DDevice7::TexBltI(LPDDRAWI_DDRAWSURFACE_LCL lpDst,
  116. LPDDRAWI_DDRAWSURFACE_LCL lpSrc,
  117. LPPOINT p, RECTL *r, DWORD dwFlags)
  118. {
  119. HRESULT ret = D3D_OK;
  120. #ifdef WINNT
  121. // WINNT allows delay create of Kernel object
  122. // if such a create fails, we can't pass handle to driver
  123. if(dwFEFlags & D3DFE_REALHAL)
  124. {
  125. if (!lpSrc->hDDSurface && !CompleteCreateSysmemSurface(lpSrc))
  126. {
  127. return DDERR_GENERIC;
  128. }
  129. if (lpDst && !lpDst->hDDSurface && !CompleteCreateSysmemSurface(lpDst))
  130. {
  131. return DDERR_GENERIC;
  132. }
  133. }
  134. #endif
  135. // If the driver supports the GetSysmemBltStatus call, then the driver can
  136. // do the Blt asynchronously. In this case, set the HARDWAREOP_STARTED
  137. // flags so that Locks and Blts to the surface(s) in concern spin until
  138. // the async Blt is finished.
  139. if((lpSrc->lpSurfMore->lpDD_lcl->lpDDCB->HALDDMiscellaneous.GetSysmemBltStatus != NULL)
  140. && (lpSrc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY))
  141. {
  142. lpSrc->lpGbl->dwGlobalFlags |= DDRAWISURFGBL_HARDWAREOPSOURCE;
  143. }
  144. if (bDP2CurrCmdOP == D3DDP2OP_TEXBLT)
  145. { // Last instruction is a tex blt, append this one to it
  146. if (dwDP2CommandLength + sizeof(D3DHAL_DP2TEXBLT) <= dwDP2CommandBufSize)
  147. {
  148. LPD3DHAL_DP2TEXBLT lpTexBlt = (LPD3DHAL_DP2TEXBLT)((LPBYTE)lpvDP2Commands +
  149. dwDP2CommandLength + dp2data.dwCommandOffset);
  150. lpDP2CurrCommand->wStateCount = ++wDP2CurrCmdCnt;
  151. lpTexBlt->dwDDDestSurface = lpDst == NULL ? 0 : lpDst->lpSurfMore->dwSurfaceHandle;
  152. lpTexBlt->dwDDSrcSurface = lpSrc->lpSurfMore->dwSurfaceHandle;
  153. lpTexBlt->pDest = *p;
  154. lpTexBlt->rSrc = *r;
  155. lpTexBlt->dwFlags = dwFlags;
  156. dwDP2CommandLength += sizeof(D3DHAL_DP2TEXBLT);
  157. D3D_INFO(6, "Modify Ins:%08lx", *(LPDWORD)lpDP2CurrCommand);
  158. return ret;
  159. }
  160. }
  161. // Check for space
  162. if (dwDP2CommandLength + sizeof(D3DHAL_DP2COMMAND) +
  163. sizeof(D3DHAL_DP2TEXBLT) > dwDP2CommandBufSize)
  164. {
  165. ret = FlushStates();
  166. if (ret != D3D_OK)
  167. {
  168. D3D_ERR("Error trying to render batched commands in TexBltI");
  169. return ret;
  170. }
  171. }
  172. // Add new renderstate instruction
  173. lpDP2CurrCommand = (LPD3DHAL_DP2COMMAND)((LPBYTE)lpvDP2Commands +
  174. dwDP2CommandLength + dp2data.dwCommandOffset);
  175. lpDP2CurrCommand->bCommand = D3DDP2OP_TEXBLT;
  176. bDP2CurrCmdOP = D3DDP2OP_TEXBLT;
  177. lpDP2CurrCommand->bReserved = 0;
  178. lpDP2CurrCommand->wStateCount = 1;
  179. wDP2CurrCmdCnt = 1;
  180. D3D_INFO(6, "Write Ins:%08lx", *(LPDWORD)lpDP2CurrCommand);
  181. // Add texture blt data
  182. LPD3DHAL_DP2TEXBLT lpTexBlt = (LPD3DHAL_DP2TEXBLT)(lpDP2CurrCommand + 1);
  183. lpTexBlt->dwDDDestSurface = lpDst == NULL ? 0 : lpDst->lpSurfMore->dwSurfaceHandle;
  184. lpTexBlt->dwDDSrcSurface = lpSrc->lpSurfMore->dwSurfaceHandle;
  185. lpTexBlt->pDest = *p;
  186. lpTexBlt->rSrc = *r;
  187. lpTexBlt->dwFlags = dwFlags;
  188. dwDP2CommandLength += sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2TEXBLT);
  189. return ret;
  190. }
  191. //---------------------------------------------------------------------
  192. //
  193. #undef DPF_MODNAME
  194. #define DPF_MODNAME "CDirect3DDevice7::SetPriorityI"
  195. HRESULT CDirect3DDevice7::SetPriorityI(LPDDRAWI_DDRAWSURFACE_LCL lpDst, DWORD dwPriority)
  196. {
  197. HRESULT ret = D3D_OK;
  198. if (bDP2CurrCmdOP == D3DDP2OP_SETPRIORITY)
  199. { // Last instruction is a set priority, append this one to it
  200. if (dwDP2CommandLength + sizeof(D3DHAL_DP2SETPRIORITY) <= dwDP2CommandBufSize)
  201. {
  202. LPD3DHAL_DP2SETPRIORITY lpSetPriority = (LPD3DHAL_DP2SETPRIORITY)((LPBYTE)lpvDP2Commands +
  203. dwDP2CommandLength + dp2data.dwCommandOffset);
  204. lpDP2CurrCommand->wStateCount = ++wDP2CurrCmdCnt;
  205. lpSetPriority->dwDDSurface = lpDst->lpSurfMore->dwSurfaceHandle;
  206. lpSetPriority->dwPriority = dwPriority;
  207. dwDP2CommandLength += sizeof(D3DHAL_DP2SETPRIORITY);
  208. D3D_INFO(6, "Modify Ins:%08lx", *(LPDWORD)lpDP2CurrCommand);
  209. return ret;
  210. }
  211. }
  212. // Check for space
  213. if (dwDP2CommandLength + sizeof(D3DHAL_DP2COMMAND) +
  214. sizeof(D3DHAL_DP2SETPRIORITY) > dwDP2CommandBufSize)
  215. {
  216. ret = FlushStates();
  217. if (ret != D3D_OK)
  218. {
  219. D3D_ERR("Error trying to render batched commands in SetPriorityI");
  220. return ret;
  221. }
  222. }
  223. // Add new setpriority instruction
  224. lpDP2CurrCommand = (LPD3DHAL_DP2COMMAND)((LPBYTE)lpvDP2Commands +
  225. dwDP2CommandLength + dp2data.dwCommandOffset);
  226. lpDP2CurrCommand->bCommand = D3DDP2OP_SETPRIORITY;
  227. bDP2CurrCmdOP = D3DDP2OP_SETPRIORITY;
  228. lpDP2CurrCommand->bReserved = 0;
  229. lpDP2CurrCommand->wStateCount = 1;
  230. wDP2CurrCmdCnt = 1;
  231. D3D_INFO(6, "Write Ins:%08lx", *(LPDWORD)lpDP2CurrCommand);
  232. // Add texture blt data
  233. LPD3DHAL_DP2SETPRIORITY lpSetPriority = (LPD3DHAL_DP2SETPRIORITY)(lpDP2CurrCommand + 1);
  234. lpSetPriority->dwDDSurface = lpDst->lpSurfMore->dwSurfaceHandle;
  235. lpSetPriority->dwPriority = dwPriority;
  236. dwDP2CommandLength += sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETPRIORITY);
  237. return ret;
  238. }
  239. //---------------------------------------------------------------------
  240. //
  241. #undef DPF_MODNAME
  242. #define DPF_MODNAME "CDirect3DDevice7::SetTexLODI"
  243. HRESULT CDirect3DDevice7::SetTexLODI(LPDDRAWI_DDRAWSURFACE_LCL lpDst, DWORD dwLOD)
  244. {
  245. HRESULT ret = D3D_OK;
  246. if (bDP2CurrCmdOP == D3DDP2OP_SETTEXLOD)
  247. { // Last instruction is a set LOD, append this one to it
  248. if (dwDP2CommandLength + sizeof(D3DHAL_DP2SETTEXLOD) <= dwDP2CommandBufSize)
  249. {
  250. LPD3DHAL_DP2SETTEXLOD lpSetTexLOD = (LPD3DHAL_DP2SETTEXLOD)((LPBYTE)lpvDP2Commands +
  251. dwDP2CommandLength + dp2data.dwCommandOffset);
  252. lpDP2CurrCommand->wStateCount = ++wDP2CurrCmdCnt;
  253. lpSetTexLOD->dwDDSurface = lpDst->lpSurfMore->dwSurfaceHandle;
  254. lpSetTexLOD->dwLOD = dwLOD;
  255. dwDP2CommandLength += sizeof(D3DHAL_DP2SETTEXLOD);
  256. D3D_INFO(6, "Modify Ins:%08lx", *(LPDWORD)lpDP2CurrCommand);
  257. return ret;
  258. }
  259. }
  260. // Check for space
  261. if (dwDP2CommandLength + sizeof(D3DHAL_DP2COMMAND) +
  262. sizeof(D3DHAL_DP2SETTEXLOD) > dwDP2CommandBufSize)
  263. {
  264. ret = FlushStates();
  265. if (ret != D3D_OK)
  266. {
  267. D3D_ERR("Error trying to render batched commands in SetTexLODI");
  268. return ret;
  269. }
  270. }
  271. // Add new set LOD instruction
  272. lpDP2CurrCommand = (LPD3DHAL_DP2COMMAND)((LPBYTE)lpvDP2Commands +
  273. dwDP2CommandLength + dp2data.dwCommandOffset);
  274. lpDP2CurrCommand->bCommand = D3DDP2OP_SETTEXLOD;
  275. bDP2CurrCmdOP = D3DDP2OP_SETTEXLOD;
  276. lpDP2CurrCommand->bReserved = 0;
  277. lpDP2CurrCommand->wStateCount = 1;
  278. wDP2CurrCmdCnt = 1;
  279. D3D_INFO(6, "Write Ins:%08lx", *(LPDWORD)lpDP2CurrCommand);
  280. // Add texture blt data
  281. LPD3DHAL_DP2SETTEXLOD lpSetTexLOD = (LPD3DHAL_DP2SETTEXLOD)(lpDP2CurrCommand + 1);
  282. lpSetTexLOD->dwDDSurface = lpDst->lpSurfMore->dwSurfaceHandle;
  283. lpSetTexLOD->dwLOD = dwLOD;
  284. dwDP2CommandLength += sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETTEXLOD);
  285. return ret;
  286. }
  287. //---------------------------------------------------------------------
  288. #undef DPF_MODNAME
  289. #define DPF_MODNAME "CDirect3DDevice7::UpdatePalette"
  290. //---------------------------------------------------------------------
  291. // This function should be called from PaletteUpdateNotify
  292. //
  293. HRESULT CDirect3DDevice7::UpdatePalette(
  294. DWORD dwPaletteHandle,
  295. DWORD dwStartIndex,
  296. DWORD dwNumberOfIndices,
  297. LPPALETTEENTRY pFirstIndex)
  298. {
  299. HRESULT ret = D3D_OK;
  300. DWORD dwSizeChange=sizeof(D3DHAL_DP2COMMAND) +
  301. sizeof(D3DHAL_DP2UPDATEPALETTE) + dwNumberOfIndices*sizeof(PALETTEENTRY);
  302. if (bDP2CurrCmdOP == D3DDP2OP_UPDATEPALETTE)
  303. { // Last instruction is a tex blt, append this one to it
  304. }
  305. // Check for space
  306. if (dwDP2CommandLength + dwSizeChange > dwDP2CommandBufSize)
  307. {
  308. ret = FlushStates();
  309. if (ret != D3D_OK)
  310. {
  311. D3D_ERR("Error trying to render batched commands in TexBltI");
  312. return ret;
  313. }
  314. }
  315. // Add new renderstate instruction
  316. lpDP2CurrCommand = (LPD3DHAL_DP2COMMAND)((LPBYTE)lpvDP2Commands +
  317. dwDP2CommandLength + dp2data.dwCommandOffset);
  318. lpDP2CurrCommand->bCommand = D3DDP2OP_UPDATEPALETTE;
  319. bDP2CurrCmdOP = D3DDP2OP_UPDATEPALETTE;
  320. lpDP2CurrCommand->bReserved = 0;
  321. lpDP2CurrCommand->wStateCount = 1;
  322. wDP2CurrCmdCnt = 1;
  323. D3D_INFO(6, "Write Ins:%08lx", *(LPDWORD)lpDP2CurrCommand);
  324. // Add texture blt data
  325. LPD3DHAL_DP2UPDATEPALETTE lpUpdatePal = (LPD3DHAL_DP2UPDATEPALETTE)(lpDP2CurrCommand + 1);
  326. lpUpdatePal->dwPaletteHandle=dwPaletteHandle;
  327. lpUpdatePal->wStartIndex=(WORD)dwStartIndex;
  328. lpUpdatePal->wNumEntries=(WORD)dwNumberOfIndices;
  329. memcpy((LPVOID)(lpUpdatePal+1),(LPVOID)pFirstIndex,
  330. dwNumberOfIndices*sizeof(PALETTEENTRY));
  331. dwDP2CommandLength += dwSizeChange;
  332. return ret;
  333. }
  334. #undef DPF_MODNAME
  335. #define DPF_MODNAME "CDirect3DDevice7::SetPalette"
  336. //---------------------------------------------------------------------
  337. // This function should be called from PaletteAssociateNotify
  338. //
  339. HRESULT CDirect3DDevice7::SetPalette(DWORD dwPaletteHandle,
  340. DWORD dwPaletteFlags,
  341. DWORD dwSurfaceHandle )
  342. {
  343. HRESULT ret = D3D_OK;
  344. DWORD dwSizeChange;
  345. if (bDP2CurrCmdOP == D3DDP2OP_SETPALETTE)
  346. { // Last instruction is a tex blt, append this one to it
  347. }
  348. dwSizeChange=sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETPALETTE);
  349. // Check for space
  350. if (dwDP2CommandLength + dwSizeChange > dwDP2CommandBufSize)
  351. {
  352. ret = FlushStates();
  353. if (ret != D3D_OK)
  354. {
  355. D3D_ERR("Error trying to render batched commands in TexBltI");
  356. return ret;
  357. }
  358. }
  359. // Add new renderstate instruction
  360. lpDP2CurrCommand = (LPD3DHAL_DP2COMMAND)((LPBYTE)lpvDP2Commands +
  361. dwDP2CommandLength + dp2data.dwCommandOffset);
  362. lpDP2CurrCommand->bCommand = D3DDP2OP_SETPALETTE;
  363. bDP2CurrCmdOP = D3DDP2OP_UPDATEPALETTE;
  364. lpDP2CurrCommand->bReserved = 0;
  365. lpDP2CurrCommand->wStateCount = 1;
  366. wDP2CurrCmdCnt = 1;
  367. D3D_INFO(6, "Write Ins:%08lx", *(LPDWORD)lpDP2CurrCommand);
  368. LPD3DHAL_DP2SETPALETTE lpSetPal = (LPD3DHAL_DP2SETPALETTE)(lpDP2CurrCommand + 1);
  369. lpSetPal->dwPaletteHandle=dwPaletteHandle;
  370. lpSetPal->dwPaletteFlags=dwPaletteFlags;
  371. lpSetPal->dwSurfaceHandle=dwSurfaceHandle;
  372. dwDP2CommandLength += dwSizeChange;
  373. return ret;
  374. }
  375. //---------------------------------------------------------------------
  376. //
  377. #undef DPF_MODNAME
  378. #define DPF_MODNAME "CDirect3DDevice7::UpdateTextures"
  379. HRESULT CDirect3DDevice7::UpdateTextures()
  380. {
  381. HRESULT result = D3D_OK;
  382. DWORD dwSavedFlags = this->dwFlags;
  383. this->dwFlags |= D3DPV_WITHINPRIMITIVE;
  384. for (DWORD dwStage = 0; dwStage < this->dwMaxTextureBlendStages; dwStage++)
  385. {
  386. D3DTEXTUREHANDLE dwDDIHandle;
  387. LPDIRECT3DTEXTUREI lpTexI = this->lpD3DMappedTexI[dwStage];
  388. if(lpTexI)
  389. {
  390. if (lpTexI->InVidmem())
  391. {
  392. if (lpTexI->bDirty)
  393. {
  394. CLockD3DST lockObject(this, DPF_MODNAME, REMIND("")); // we access DDraw gbl in CopySurface
  395. // 0xFFFFFFFF is equivalent to ALL_FACES, but in addition indicates to CopySurface
  396. // that this is a sysmem -> vidmem transfer.
  397. result = CopySurface(lpTexI->lpDDS,NULL,lpTexI->lpDDSSys,NULL,0xFFFFFFFF);
  398. if (DD_OK != result)
  399. {
  400. D3D_ERR("Error copying surface while updating textures");
  401. goto l_exit;
  402. }
  403. else
  404. {
  405. lpTexI->bDirty=FALSE;
  406. D3D_INFO(4,"UpdateTextures: Dirty texture updated");
  407. }
  408. }
  409. }
  410. else
  411. {
  412. if(lpTexI->D3DManaged())
  413. {
  414. // Not in vidmem, so we need to call GetTextureDDIHandle
  415. m_dwStageDirty |= (1 << dwStage);
  416. }
  417. }
  418. if (m_dwStageDirty & (1 << dwStage))
  419. {
  420. result = GetTextureDDIHandle(lpTexI, &dwDDIHandle);
  421. if (result != D3D_OK)
  422. {
  423. D3D_ERR("Failed to get texture handle");
  424. goto l_exit;
  425. }
  426. BatchTexture(((LPDDRAWI_DDRAWSURFACE_INT)lpTexI->lpDDS)->lpLcl);
  427. m_dwStageDirty &= ~(1 << dwStage); // reset stage dirty
  428. }
  429. else
  430. {
  431. continue; // Ok, then nothing needs to be done further
  432. }
  433. }
  434. else if (m_dwStageDirty & (1 << dwStage))
  435. {
  436. dwDDIHandle = 0; //tell driver to disable this texture
  437. m_dwStageDirty &= ~(1 << dwStage); // reset stage dirty
  438. }
  439. else
  440. {
  441. continue;
  442. }
  443. result = SetTSSI(dwStage, (D3DTEXTURESTAGESTATETYPE)D3DTSS_TEXTUREMAP, dwDDIHandle);
  444. if(result != D3D_OK)
  445. {
  446. D3D_ERR("Failed to batch set texture instruction");
  447. goto l_exit;
  448. }
  449. // Update runtime copy of state.
  450. this->tsstates[dwStage][D3DTSS_TEXTUREMAP] = dwDDIHandle;
  451. }
  452. l_exit:
  453. this->dwFlags = dwSavedFlags;
  454. return result;
  455. }
  456. //---------------------------------------------------------------------
  457. #undef DPF_MODNAME
  458. #define DPF_MODNAME "CDirect3DDevice7::GetTextureDDIHandle"
  459. HRESULT CDirect3DDevice7::GetTextureDDIHandle(LPDIRECT3DTEXTUREI lpTexI, D3DTEXTUREHANDLE *phTex)
  460. {
  461. if(lpTexI->D3DManaged())
  462. {
  463. if(!lpTexI->InVidmem())
  464. {
  465. HRESULT ret = lpDirect3DI->lpTextureManager->allocNode(lpTexI, this);
  466. if (D3D_OK != ret)
  467. {
  468. D3D_ERR("Failed to create video memory surface");
  469. return ret;
  470. }
  471. }
  472. lpDirect3DI->lpTextureManager->TimeStamp(lpTexI);
  473. }
  474. *phTex = lpTexI->m_hTex;
  475. return D3D_OK;
  476. }
  477. void CDirect3DDevice7::SetRenderTargetI(LPDIRECTDRAWSURFACE pRenderTarget, LPDIRECTDRAWSURFACE pZBuffer)
  478. {
  479. LPD3DHAL_DP2SETRENDERTARGET pData;
  480. pData = (LPD3DHAL_DP2SETRENDERTARGET)GetHalBufferPointer(D3DDP2OP_SETRENDERTARGET, sizeof(*pData));
  481. pData->hRenderTarget = ((LPDDRAWI_DDRAWSURFACE_INT)pRenderTarget)->lpLcl->lpSurfMore->dwSurfaceHandle;
  482. if (pZBuffer)
  483. pData->hZBuffer = ((LPDDRAWI_DDRAWSURFACE_INT)pZBuffer)->lpLcl->lpSurfMore->dwSurfaceHandle;
  484. else
  485. pData->hZBuffer = 0;
  486. // Flush before switching RenderTarget..
  487. HRESULT ret = FlushStates();
  488. if (ret != D3D_OK)
  489. {
  490. D3D_ERR("Error trying to FlushStates in SetRenderTarget");
  491. throw ret;
  492. }
  493. }
  494. void CDirect3DDevice7::SetRenderTargetINoFlush(LPDIRECTDRAWSURFACE pRenderTarget, LPDIRECTDRAWSURFACE pZBuffer)
  495. {
  496. LPD3DHAL_DP2SETRENDERTARGET pData;
  497. pData = (LPD3DHAL_DP2SETRENDERTARGET)GetHalBufferPointer(D3DDP2OP_SETRENDERTARGET, sizeof(*pData));
  498. pData->hRenderTarget = ((LPDDRAWI_DDRAWSURFACE_INT)pRenderTarget)->lpLcl->lpSurfMore->dwSurfaceHandle;
  499. if (pZBuffer)
  500. pData->hZBuffer = ((LPDDRAWI_DDRAWSURFACE_INT)pZBuffer)->lpLcl->lpSurfMore->dwSurfaceHandle;
  501. else
  502. pData->hZBuffer = 0;
  503. }
  504. //---------------------------------------------------------------------
  505. #undef DPF_MODNAME
  506. #define DPF_MODNAME "CDirect3DDevice7::CanDoTexBlt"
  507. bool CDirect3DDevice7::CanDoTexBlt(LPDDRAWI_DDRAWSURFACE_LCL lpDDSSrcSubFace_lcl,
  508. LPDDRAWI_DDRAWSURFACE_LCL lpDDSDstSubFace_lcl)
  509. {
  510. if(dwFEFlags & D3DFE_REALHAL)
  511. {
  512. DWORD &srccaps = lpDDSSrcSubFace_lcl->ddsCaps.dwCaps;
  513. DWORD &dstcaps = lpDDSDstSubFace_lcl->ddsCaps.dwCaps;
  514. DDCORECAPS &ddcaps = ((LPDDRAWI_DIRECTDRAW_INT)(lpDirect3DI->lpDD7))->lpLcl->lpGbl->ddCaps;
  515. if(srccaps & DDSCAPS_VIDEOPORT)
  516. {
  517. return false;
  518. }
  519. DDPIXELFORMAT &srcpf = PixelFormat(lpDDSSrcSubFace_lcl);
  520. DDPIXELFORMAT &dstpf = PixelFormat(lpDDSDstSubFace_lcl);
  521. if(!MatchDDPIXELFORMAT(&srcpf, &dstpf))
  522. {
  523. return false;
  524. }
  525. else if((srcpf.dwFlags & DDPF_FOURCC) && srcpf.dwFourCC == dstpf.dwFourCC &&
  526. !(ddcaps.dwCaps2 & DDCAPS2_COPYFOURCC))
  527. {
  528. return false;
  529. }
  530. if(ddcaps.dwCaps2 & DDCAPS2_NONLOCALVIDMEMCAPS)
  531. {
  532. if(srccaps & DDSCAPS_SYSTEMMEMORY)
  533. {
  534. if((dstcaps & DDSCAPS_NONLOCALVIDMEM) && (this->d3dDevDesc.dwDevCaps & D3DDEVCAPS_CANBLTSYSTONONLOCAL))
  535. {
  536. return true;
  537. }
  538. else if((dstcaps & DDSCAPS_LOCALVIDMEM) && (ddcaps.dwSVBCaps & DDCAPS_BLT))
  539. {
  540. return true;
  541. }
  542. else
  543. {
  544. return false;
  545. }
  546. }
  547. else if(srccaps & DDSCAPS_NONLOCALVIDMEM)
  548. {
  549. LPDDNONLOCALVIDMEMCAPS &lpnlvcaps = ((LPDDRAWI_DIRECTDRAW_INT)lpDirect3DI->lpDD7)->lpLcl->lpGbl->lpddNLVCaps;
  550. DDASSERT(lpnlvcaps);
  551. if((dstcaps & DDSCAPS_LOCALVIDMEM) && (lpnlvcaps->dwNLVBCaps & DDCAPS_BLT))
  552. {
  553. return true;
  554. }
  555. else
  556. {
  557. return false;
  558. }
  559. }
  560. else if(srccaps & DDSCAPS_LOCALVIDMEM)
  561. {
  562. if((dstcaps & DDSCAPS_LOCALVIDMEM) && (ddcaps.dwCaps & DDCAPS_BLT))
  563. {
  564. return true;
  565. }
  566. else
  567. {
  568. return false;
  569. }
  570. }
  571. else
  572. {
  573. return false;
  574. }
  575. }
  576. else
  577. {
  578. if(srccaps & DDSCAPS_SYSTEMMEMORY)
  579. {
  580. if((dstcaps & DDSCAPS_VIDEOMEMORY) && (ddcaps.dwSVBCaps & DDCAPS_BLT))
  581. {
  582. return true;
  583. }
  584. else
  585. {
  586. return false;
  587. }
  588. }
  589. else if(srccaps & DDSCAPS_VIDEOMEMORY)
  590. {
  591. if((dstcaps & DDSCAPS_VIDEOMEMORY) && (ddcaps.dwCaps & DDCAPS_BLT))
  592. {
  593. return true;
  594. }
  595. else
  596. {
  597. return false;
  598. }
  599. }
  600. else
  601. {
  602. return false;
  603. }
  604. }
  605. }
  606. return false;
  607. }
  608. //---------------------------------------------------------------------
  609. #undef DPF_MODNAME
  610. #define DPF_MODNAME "CDirect3DDevice7::ClearI"
  611. void CDirect3DDevice7::ClearI(DWORD dwFlags, DWORD clrCount, D3DCOLOR dwColor, D3DVALUE dvZ, DWORD dwStencil)
  612. {
  613. DWORD dwCommandSize = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2CLEAR) + sizeof(RECT) * (clrCount - 1);
  614. // Check to see if there is space to add a new command for space
  615. if (dwCommandSize + dwDP2CommandLength > dwDP2CommandBufSize)
  616. {
  617. HRESULT ret = FlushStates();
  618. if (ret != D3D_OK)
  619. {
  620. D3D_ERR("Error trying to render batched commands in CDirect3DDevice7::ClearI");
  621. throw ret;
  622. }
  623. }
  624. lpDP2CurrCommand = (LPD3DHAL_DP2COMMAND)((LPBYTE)lpvDP2Commands +
  625. dwDP2CommandLength + dp2data.dwCommandOffset);
  626. lpDP2CurrCommand->bCommand = D3DDP2OP_CLEAR;
  627. bDP2CurrCmdOP = D3DDP2OP_CLEAR;
  628. lpDP2CurrCommand->bReserved = 0;
  629. wDP2CurrCmdCnt = (WORD)clrCount;
  630. lpDP2CurrCommand->wStateCount = wDP2CurrCmdCnt;
  631. D3D_INFO(6, "Write Ins:%08lx", *(LPDWORD)lpDP2CurrCommand);
  632. dwDP2CommandLength += dwCommandSize;
  633. // Write data
  634. LPD3DHAL_DP2CLEAR pData = (LPD3DHAL_DP2CLEAR)(lpDP2CurrCommand + 1);
  635. pData->dwFlags = dwFlags;
  636. pData->dwFillColor = dwColor;
  637. pData->dvFillDepth = dvZ;
  638. pData->dwFillStencil = dwStencil;
  639. memcpy(pData->Rects, clrRects, clrCount * sizeof(D3DRECT));
  640. }
  641. //---------------------------------------------------------------------
  642. #undef DPF_MODNAME
  643. #define DPF_MODNAME "CDirect3DDevice7::GetInfo"
  644. HRESULT D3DAPI CDirect3DDevice7::GetInfo(DWORD dwDevInfoID, LPVOID pDevInfoStruct, DWORD dwSize)
  645. {
  646. CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
  647. // Release in the destructor
  648. if (!VALID_DIRECT3DDEVICE_PTR(this))
  649. {
  650. D3D_ERR( "Invalid DIRECT3DDEVICE7 pointer" );
  651. return DDERR_INVALIDOBJECT;
  652. }
  653. if (dwSize == 0 || !VALID_D3DDEVINFOSTRUCT_PTR(pDevInfoStruct, dwSize))
  654. {
  655. D3D_ERR( "Invalid structure pointer or size" );
  656. return DDERR_INVALIDOBJECT;
  657. }
  658. memset(pDevInfoStruct, 0, dwSize);
  659. #if DBG
  660. if (this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INSCENE)
  661. {
  662. D3D_WARN( 2, "GetInfo called within a scene" );
  663. }
  664. if( this->pfnGetDriverState == NULL )
  665. {
  666. D3D_ERR( "GetDriverState not implemented by the driver" );
  667. DDASSERT( this->pfnGetDriverState );
  668. }
  669. #endif
  670. try
  671. {
  672. switch(dwDevInfoID)
  673. {
  674. #if COLLECTSTATS
  675. case D3DDEVINFOID_TEXTUREMANAGER:
  676. if(!(((LPDDRAWI_DIRECTDRAW_INT)(this->lpDirect3DI->lpDD7))->lpLcl->lpGbl->ddCaps.dwCaps2 & DDCAPS2_CANMANAGETEXTURE))
  677. {
  678. lpDirect3DI->lpTextureManager->GetStats((LPD3DDEVINFO_TEXTUREMANAGER)pDevInfoStruct);
  679. return D3D_OK;
  680. }
  681. break;
  682. #else
  683. case D3DDEVINFOID_TEXTUREMANAGER:
  684. D3D_WARN( 0, "Stats not collected in this build" );
  685. return S_FALSE;
  686. #endif
  687. default:
  688. if(GetInfoInternal(dwDevInfoID, pDevInfoStruct, dwSize))
  689. return D3D_OK;
  690. }
  691. HRESULT hr = FlushStates();
  692. if(hr != D3D_OK)
  693. {
  694. D3D_ERR("Error flushing device");
  695. return hr;
  696. }
  697. }
  698. catch(HRESULT ret)
  699. {
  700. memset(pDevInfoStruct, 0, dwSize);
  701. return ret;
  702. }
  703. HRESULT hr;
  704. DDHAL_GETDRIVERSTATEDATA dsd;
  705. dsd.dwFlags = dwDevInfoID;
  706. dsd.dwhContext = this->dwhContext;
  707. dsd.lpdwStates = (LPDWORD)pDevInfoStruct;
  708. dsd.dwLength = dwSize;
  709. LOCK_HAL(hr, this);
  710. hr = this->pfnGetDriverState(&dsd);
  711. UNLOCK_HAL(this);
  712. if (hr != DDHAL_DRIVER_HANDLED)
  713. {
  714. D3D_WARN( 1, "Device information query unsupported" );
  715. memset(pDevInfoStruct, 0, dwSize);
  716. return S_FALSE;
  717. }
  718. else if (dsd.ddRVal != DD_OK)
  719. {
  720. D3D_INFO(1,"Driver failed GetInfo");
  721. memset(pDevInfoStruct, 0, dwSize);
  722. return E_FAIL;
  723. }
  724. return D3D_OK;
  725. }
  726. //=====================================================================
  727. //
  728. // CDirect3DDeviceTL interface
  729. //
  730. //=====================================================================
  731. CDirect3DDeviceTL::CDirect3DDeviceTL()
  732. {
  733. deviceType = D3DDEVTYPE_DX7TLHAL;
  734. m_rsMax = D3D_MAXRENDERSTATES;
  735. }
  736. //---------------------------------------------------------------------
  737. #undef DPF_MODNAME
  738. #define DPF_MODNAME "CDirect3DDeviceTL::Init"
  739. HRESULT CDirect3DDeviceTL::Init(
  740. REFCLSID riid, LPDIRECT3DI lpD3DI, LPDIRECTDRAWSURFACE lpDDS,
  741. IUnknown* pUnkOuter, LPUNKNOWN* lplpD3DDevice)
  742. {
  743. this->dwFEFlags |= D3DFE_TLHAL;
  744. #if 0
  745. // Stateblocks are always emulated on DX7
  746. DWORD value = 0;
  747. GetD3DRegValue(REG_DWORD, "EmulateStateBlocks", &value, sizeof(DWORD));
  748. if(value == 0)
  749. {
  750. // All DX7 devices should support state sets
  751. this->dwFEFlags |= D3DFE_STATESETS;
  752. }
  753. #endif
  754. HRESULT ret = CDirect3DDevice7::Init(riid, lpD3DI, lpDDS, pUnkOuter, lplpD3DDevice);
  755. if (ret != D3D_OK)
  756. return ret;
  757. // Do device specific initialization here
  758. return D3D_OK;
  759. }
  760. //---------------------------------------------------------------------
  761. #undef DPF_MODNAME
  762. #define DPF_MODNAME "CDirect3DDeviceTL::MaterialChanged"
  763. void CDirect3DDeviceTL::MaterialChanged()
  764. {
  765. // Update front-end state (for ProcessVertices calls)
  766. DIRECT3DDEVICEI::MaterialChanged();
  767. // Driver should not be called because it will execute the macro)
  768. if (this->dwFEFlags & D3DFE_EXECUTESTATEMODE)
  769. return;
  770. LPD3DHAL_DP2SETMATERIAL pData;
  771. pData = (LPD3DHAL_DP2SETMATERIAL)GetHalBufferPointer(D3DDP2OP_SETMATERIAL, sizeof(*pData));
  772. *pData = this->lighting.material;
  773. }
  774. //---------------------------------------------------------------------
  775. #undef DPF_MODNAME
  776. #define DPF_MODNAME "CDirect3DDeviceTL::SetClipPlaneI"
  777. void CDirect3DDeviceTL::SetClipPlaneI(DWORD dwPlaneIndex, D3DVALUE* pPlaneEquation)
  778. {
  779. // Update front-end state (for DrawPrimitiveStrided calls)
  780. DIRECT3DDEVICEI::SetClipPlaneI(dwPlaneIndex, pPlaneEquation);
  781. // Driver should not be called because it will execute the macro)
  782. if (this->dwFEFlags & D3DFE_EXECUTESTATEMODE)
  783. return;
  784. #if DBG
  785. if (dwPlaneIndex >= this->transform.dwMaxUserClipPlanes)
  786. {
  787. D3D_WARN(1, "Device does not support that many clipping planes");
  788. return;
  789. }
  790. #endif
  791. LPD3DHAL_DP2SETCLIPPLANE pData;
  792. pData = (LPD3DHAL_DP2SETCLIPPLANE)GetHalBufferPointer(D3DDP2OP_SETCLIPPLANE, sizeof(*pData));
  793. pData->dwIndex = dwPlaneIndex;
  794. pData->plane[0] = pPlaneEquation[0];
  795. pData->plane[1] = pPlaneEquation[1];
  796. pData->plane[2] = pPlaneEquation[2];
  797. pData->plane[3] = pPlaneEquation[3];
  798. }
  799. //---------------------------------------------------------------------
  800. #undef DPF_MODNAME
  801. #define DPF_MODNAME "CDirect3DDeviceTL::LightChanged"
  802. void CDirect3DDeviceTL::LightChanged(DWORD dwLightIndex)
  803. {
  804. // Update front-end state (for ProcessVertices calls)
  805. LPDIRECT3DLIGHTI pLight = &m_pLights[dwLightIndex];
  806. BOOL bValid = pLight->Valid(); // Valid bit will be set in LightChanged
  807. DIRECT3DDEVICEI::LightChanged(dwLightIndex);
  808. // If this is first time we set the light data, we call HALL to create
  809. // light. HAL could grow the internal light list at this time
  810. if (!bValid)
  811. {
  812. LPD3DHAL_DP2CREATELIGHT pData;
  813. pData = (LPD3DHAL_DP2CREATELIGHT)GetHalBufferPointer(D3DDP2OP_CREATELIGHT, sizeof(*pData));
  814. pData->dwIndex = dwLightIndex;
  815. pLight->m_LightI.flags |= D3DLIGHTI_VALID;
  816. }
  817. if (this->dwFEFlags & D3DFE_EXECUTESTATEMODE)
  818. return;
  819. LPD3DHAL_DP2SETLIGHT pData;
  820. pData = (LPD3DHAL_DP2SETLIGHT)GetHalBufferPointer(D3DDP2OP_SETLIGHT,
  821. sizeof(*pData)+sizeof(D3DLIGHT7));
  822. pData->dwIndex = dwLightIndex;
  823. pData->dwDataType = D3DHAL_SETLIGHT_DATA;
  824. *(D3DLIGHT7 *)((LPBYTE)pData + sizeof(D3DHAL_DP2SETLIGHT)) =
  825. pLight->m_Light;
  826. }
  827. //---------------------------------------------------------------------
  828. // Nothing to do here, because render state is used to enable/disable
  829. // lights
  830. //
  831. #undef DPF_MODNAME
  832. #define DPF_MODNAME "CDirect3DDeviceTL::LightEnableI"
  833. void CDirect3DDeviceTL::LightEnableI(DWORD dwLightIndex, BOOL bEnable)
  834. {
  835. DIRECT3DDEVICEI::LightEnableI(dwLightIndex, bEnable);
  836. if (!(this->dwFEFlags & D3DFE_EXECUTESTATEMODE))
  837. {
  838. LPD3DHAL_DP2SETLIGHT pData;
  839. pData = (LPD3DHAL_DP2SETLIGHT)GetHalBufferPointer(D3DDP2OP_SETLIGHT, sizeof(*pData));
  840. pData->dwIndex = dwLightIndex;
  841. if (bEnable)
  842. pData->dwDataType = D3DHAL_SETLIGHT_ENABLE;
  843. else
  844. pData->dwDataType = D3DHAL_SETLIGHT_DISABLE;
  845. }
  846. }
  847. //---------------------------------------------------------------------
  848. #undef DPF_MODNAME
  849. #define DPF_MODNAME "CDirect3DDeviceTL::SetTransformI"
  850. void CDirect3DDeviceTL::SetTransformI(D3DTRANSFORMSTATETYPE type,
  851. LPD3DMATRIX pMat)
  852. {
  853. DDASSERT(pMat != NULL);
  854. DIRECT3DDEVICEI::SetTransformI(type, pMat);
  855. if (!(this->dwFEFlags & D3DFE_EXECUTESTATEMODE))
  856. {
  857. LPD3DHAL_DP2SETTRANSFORM pData;
  858. pData = (LPD3DHAL_DP2SETTRANSFORM)GetHalBufferPointer(D3DDP2OP_SETTRANSFORM, sizeof(*pData));
  859. pData->xfrmType = type;
  860. pData->matrix = *pMat;
  861. }
  862. }
  863. //---------------------------------------------------------------------
  864. // ProcessPrimitive processes indexed and non-indexed primitives
  865. // as defined by "op"
  866. // It is assumed that only untransformed vertices are passed to this function
  867. //
  868. // op = __PROCPRIMOP_NONINDEXEDPRIM by default
  869. //
  870. #undef DPF_MODNAME
  871. #define DPF_MODNAME "CDirect3DDeviceTL::ProcessPrimitive"
  872. HRESULT CDirect3DDeviceTL::ProcessPrimitive(__PROCPRIMOP op)
  873. {
  874. HRESULT ret;
  875. #if DBG
  876. // Do some validation
  877. if (!FVF_TRANSFORMED(this->dwVIDIn))
  878. {
  879. if (this->rstates[D3DRENDERSTATE_VERTEXBLEND])
  880. {
  881. if(this->rstates[D3DRENDERSTATE_VERTEXBLEND] + 1 > this->d3dDevDesc.wMaxVertexBlendMatrices)
  882. {
  883. D3D_WARN(1, "Device does not support that many blend weights");
  884. }
  885. }
  886. }
  887. #endif
  888. this->dwVIDOut = this->dwVIDIn;
  889. if (this->dwDeviceFlags & D3DDEV_STRIDE)
  890. {
  891. DWORD dwTexCoordSizeDummy[8];
  892. DWORD dwFVF = this->dwVIDIn;
  893. DWORD dwPositionSize = GetPositionSizeFVF(dwFVF);
  894. DWORD dwVertexSize = GetVertexSizeFVF(dwFVF) +
  895. ComputeTextureCoordSize(dwFVF, dwTexCoordSizeDummy);
  896. this->dwOutputSize = dwVertexSize;
  897. this->dwVertexPoolSize = this->dwNumVertices * dwVertexSize;
  898. if (this->TLVbuf_Grow(this->dwVertexPoolSize, true) != D3D_OK)
  899. {
  900. D3D_ERR( "Could not grow TL vertex buffer" );
  901. return DDERR_OUTOFMEMORY;
  902. }
  903. ret = this->StartPrimVB(this->TLVbuf_GetVBI(), 0);
  904. if (ret != D3D_OK)
  905. return ret;
  906. D3DVALUE *p = (D3DVALUE*)this->TLVbuf_GetAddress();
  907. for (DWORD n = this->dwNumVertices; n; n--)
  908. {
  909. // XYZ and wheights
  910. memcpy(p, this->position.lpvData, dwPositionSize);
  911. p = (D3DVALUE*)((BYTE*)p + dwPositionSize);
  912. this->position.lpvData = (char*)this->position.lpvData + this->position.dwStride;
  913. if (dwFVF & D3DFVF_NORMAL)
  914. {
  915. *p++ = ((D3DVALUE*)this->normal.lpvData)[0];
  916. *p++ = ((D3DVALUE*)this->normal.lpvData)[1];
  917. *p++ = ((D3DVALUE*)this->normal.lpvData)[2];
  918. this->normal.lpvData = (char*)this->normal.lpvData + this->normal.dwStride;
  919. }
  920. if (dwFVF & D3DFVF_RESERVED1)
  921. {
  922. *p++ = 0;
  923. }
  924. if (dwFVF & D3DFVF_DIFFUSE)
  925. {
  926. *p++ = *(D3DVALUE*)this->diffuse.lpvData;
  927. this->diffuse.lpvData = (char*)this->diffuse.lpvData + this->diffuse.dwStride;
  928. }
  929. if (dwFVF & D3DFVF_SPECULAR)
  930. {
  931. *p++ = *(D3DVALUE*)this->specular.lpvData;
  932. this->specular.lpvData = (char*)this->specular.lpvData + this->specular.dwStride;
  933. }
  934. for (DWORD i=0; i < this->nTexCoord; i++)
  935. {
  936. DWORD dwSize = dwTexCoordSizeDummy[i];
  937. memcpy(p, this->textures[i].lpvData, dwSize);
  938. this->textures[i].lpvData = (char*)this->textures[i].lpvData + this->textures[i].dwStride;
  939. p = (D3DVALUE*)((char*)p + dwSize);
  940. }
  941. }
  942. }
  943. else
  944. {
  945. // Pass vertices directly from the user memory
  946. this->dwOutputSize = this->position.dwStride;
  947. this->lpvOut = this->position.lpvData;
  948. this->dwVertexPoolSize = this->dwNumVertices * this->dwOutputSize;
  949. ret = this->StartPrimUserMem(this->position.lpvData);
  950. if (ret != D3D_OK)
  951. return ret;
  952. }
  953. if (op == __PROCPRIMOP_INDEXEDPRIM)
  954. {
  955. ret = this->DrawIndexPrim();
  956. }
  957. else
  958. { // Non indexed primitive
  959. ret = this->DrawPrim();
  960. }
  961. if (ret != D3D_OK)
  962. return ret;
  963. return this->EndPrim();
  964. }
  965. //---------------------------------------------------------------------
  966. #undef DPF_MODNAME
  967. #define DPF_MODNAME "CDirect3DDeviceTL::UpdateDrvViewInfo"
  968. void CDirect3DDeviceTL::UpdateDrvViewInfo(LPD3DVIEWPORT7 lpVwpData)
  969. {
  970. // Update viewport size
  971. CDirect3DDeviceIDP2::UpdateDrvViewInfo(lpVwpData);
  972. // Update Z range
  973. LPD3DHAL_DP2ZRANGE pData;
  974. pData = (LPD3DHAL_DP2ZRANGE)GetHalBufferPointer(D3DDP2OP_ZRANGE, sizeof(*pData));
  975. pData->dvMinZ = lpVwpData->dvMinZ;
  976. pData->dvMaxZ = lpVwpData->dvMaxZ;
  977. }
  978. //---------------------------------------------------------------------
  979. #undef DPF_MODNAME
  980. #define DPF_MODNAME "CDirect3DDeviceTL::SetupFVFData"
  981. HRESULT CDirect3DDeviceTL::SetupFVFData(DWORD *pdwInpVertexSize)
  982. {
  983. this->dwFEFlags &= ~D3DFE_FVF_DIRTY;
  984. this->nTexCoord = FVF_TEXCOORD_NUMBER(this->dwVIDIn);
  985. DWORD dwSize = GetVertexSizeFVF(this->dwVIDIn);
  986. // Add size of texture coordinates
  987. DWORD dwTextureFormats = this->dwVIDIn >> 16;
  988. for (DWORD i=this->nTexCoord; i; i--)
  989. {
  990. dwSize += g_TextureSize[dwTextureFormats & 0x3];
  991. dwTextureFormats >>= 2;
  992. }
  993. if (pdwInpVertexSize)
  994. *pdwInpVertexSize = dwSize;
  995. // In case if COLORVERTEX is TRUE, the vertexAlpha could be overriden
  996. // by vertex alpha
  997. this->lighting.alpha = (DWORD)this->lighting.materialAlpha;
  998. this->lighting.alphaSpecular = (DWORD)this->lighting.materialAlphaS;
  999. return D3D_OK;
  1000. }