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.

806 lines
30 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * D3D SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: d3dsurf.c
  8. *
  9. * Content: Surface management callbacks for D3D
  10. *
  11. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "glint.h"
  15. #include "dma.h"
  16. //@@BEGIN_DDKSPLIT
  17. #if DBG
  18. // Whistler bug 281090 detection func, print warning msg only, remove later
  19. void
  20. vDetectMixedMIPLevels(
  21. LPDDRAWI_DDRAWSURFACE_LCL pTopLevel)
  22. {
  23. LPDDRAWI_DDRAWSURFACE_LCL pCurLevel;
  24. DWORD dwMIPCaps;
  25. // Check whether this is a MIP texture
  26. dwMIPCaps = DDSCAPS_COMPLEX | DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
  27. if ((pTopLevel->ddsCaps.dwCaps & dwMIPCaps) != dwMIPCaps)
  28. {
  29. return;
  30. }
  31. // Check whether all the levels have the same cap bits
  32. pCurLevel = pTopLevel;
  33. do
  34. {
  35. if (pCurLevel->ddsCaps.dwCaps != pTopLevel->ddsCaps.dwCaps)
  36. {
  37. DISPDBG((ERRLVL,
  38. "BUG281090 : MIP levels of mixed type (0x%x : 0x%x, 0x%x)",
  39. pTopLevel->lpSurfMore->dwSurfaceHandle,
  40. pCurLevel->ddsCaps.dwCaps, pTopLevel->ddsCaps.dwCaps));
  41. }
  42. if (pCurLevel->lpAttachList)
  43. {
  44. pCurLevel = pCurLevel->lpAttachList->lpAttached;
  45. }
  46. else
  47. {
  48. break;
  49. }
  50. } while ((pCurLevel != NULL) && (pCurLevel != pTopLevel));
  51. }
  52. #endif
  53. //@@END_DDKSPLIT
  54. //-----------------------------Public Routine----------------------------------
  55. //
  56. // D3DCreateSurfaceEx
  57. //
  58. // D3dCreateSurfaceEx creates a Direct3D surface from a DirectDraw surface and
  59. // associates a requested handle value to it.
  60. //
  61. // All Direct3D drivers must support D3dCreateSurfaceEx.
  62. //
  63. // D3dCreateSurfaceEx creates an association between a DirectDraw surface and
  64. // a small integer surface handle. By creating these associations between a
  65. // handle and a DirectDraw surface, D3dCreateSurfaceEx allows a surface handle
  66. // to be imbedded in the Direct3D command stream. For example when the
  67. // D3DDP2OP_TEXBLT command token is sent to D3dDrawPrimitives2 to load a texture
  68. // map, it uses a source handle and destination handle which were associated
  69. // with a DirectDraw surface through D3dCreateSurfaceEx.
  70. //
  71. // For every DirectDraw surface created under the local DirectDraw object, the
  72. // runtime generates a valid handle that uniquely identifies the surface and
  73. // places it in pcsxd->lpDDSLcl->lpSurfMore->dwSurfaceHandle. This handle value
  74. // is also used with the D3DRENDERSTATE_TEXTUREHANDLE render state to enable
  75. // texturing, and with the D3DDP2OP_SETRENDERTARGET and D3DDP2OP_CLEAR commands
  76. // to set and/or clear new rendering and depth buffers. The driver should fail
  77. // the call and return DDHAL_DRIVER_HANDLE if it cannot create the Direct3D
  78. // surface.
  79. //
  80. // As appropriate, the driver should also store any surface-related information
  81. // that it will subsequently need when using the surface. The driver must create
  82. // a new surface table for each new lpDDLcl and implicitly grow the table when
  83. // necessary to accommodate more surfaces. Typically this is done with an
  84. // exponential growth algorithm so that you don't have to grow the table too
  85. // often. Direct3D calls D3dCreateSurfaceEx after the surface is created by
  86. // DirectDraw by request of the Direct3D runtime or the application.
  87. //
  88. // Parameters
  89. //
  90. // lpcsxd
  91. // pointer to CreateSurfaceEx structure that contains the information
  92. // required for the driver to create the surface (described below).
  93. //
  94. // dwFlags
  95. // Currently unused
  96. // lpDDLcl
  97. // Handle to the DirectDraw object created by the application.
  98. // This is the scope within which the lpDDSLcl handles exist.
  99. // A DD_DIRECTDRAW_LOCAL structure describes the driver.
  100. // lpDDSLcl
  101. // Handle to the DirectDraw surface we are being asked to
  102. // create for Direct3D. These handles are unique within each
  103. // different DD_DIRECTDRAW_LOCAL. A DD_SURFACE_LOCAL structure
  104. // represents the created surface object.
  105. // ddRVal
  106. // Specifies the location in which the driver writes the return
  107. // value of the D3dCreateSurfaceEx callback. A return code of
  108. // DD_OK indicates success.
  109. //
  110. // Return Value
  111. //
  112. // DDHAL_DRIVER_HANDLE
  113. // DDHAL_DRIVER_NOTHANDLE
  114. //
  115. //-----------------------------------------------------------------------------
  116. DWORD CALLBACK
  117. D3DCreateSurfaceEx(
  118. LPDDHAL_CREATESURFACEEXDATA lpcsxd )
  119. {
  120. P3_THUNKEDDATA *pThisDisplay;
  121. PointerArray* pSurfaceArray;
  122. GET_THUNKEDDATA(pThisDisplay, lpcsxd->lpDDLcl->lpGbl);
  123. DBG_CB_ENTRY(D3DCreateSurfaceEx);
  124. DISPDBG((DBGLVL,"D3DCreateSurfaceEx surface %d @ %x caps = %x",
  125. (DWORD)lpcsxd->lpDDSLcl->lpSurfMore->dwSurfaceHandle,
  126. lpcsxd->lpDDSLcl->lpGbl->fpVidMem,
  127. lpcsxd->lpDDSLcl->ddsCaps.dwCaps));
  128. // Get a pointer to an array of DWORD's containing surfaces
  129. pSurfaceArray = (PointerArray*)HT_GetEntry(pThisDisplay->pDirectDrawLocalsHashTable,
  130. (ULONG_PTR)lpcsxd->lpDDLcl);
  131. // If there isn't a handle set for this directdraw object, create one.
  132. if (!pSurfaceArray)
  133. {
  134. DISPDBG((DBGLVL,"Creating new pointer array for PDDLcl 0x%x",
  135. lpcsxd->lpDDLcl));
  136. pSurfaceArray = PA_CreateArray();
  137. if (pSurfaceArray)
  138. {
  139. PA_SetDataDestroyCallback(pSurfaceArray,
  140. _D3D_SU_SurfaceArrayDestroyCallback);
  141. if(!HT_AddEntry(pThisDisplay->pDirectDrawLocalsHashTable,
  142. (ULONG_PTR)lpcsxd->lpDDLcl,
  143. pSurfaceArray))
  144. {
  145. // failed to add entry, noe cleanup and exit
  146. // We ran out of memory. Cleanup before we leave
  147. PA_DestroyArray(pSurfaceArray, pThisDisplay);
  148. DISPDBG((ERRLVL,"ERROR: Couldn't allocate "
  149. "surface internal data mem for pSurfaceArray"));
  150. lpcsxd->ddRVal = DDERR_OUTOFMEMORY;
  151. DBG_CB_EXIT(D3DCreateSurfaceEx,lpcsxd->ddRVal);
  152. return DDHAL_DRIVER_HANDLED;
  153. }
  154. }
  155. else
  156. {
  157. DISPDBG((ERRLVL,"ERROR: Couldn't allocate "
  158. "surface internal data mem"));
  159. lpcsxd->ddRVal = DDERR_OUTOFMEMORY;
  160. DBG_CB_EXIT(D3DCreateSurfaceEx,lpcsxd->ddRVal);
  161. return DDHAL_DRIVER_HANDLED;
  162. }
  163. }
  164. // Recursively record the surface(s)
  165. lpcsxd->ddRVal = _D3D_SU_SurfInternalSetDataRecursive(pThisDisplay,
  166. pSurfaceArray,
  167. lpcsxd->lpDDLcl,
  168. lpcsxd->lpDDSLcl,
  169. lpcsxd->lpDDSLcl);
  170. //@@BEGIN_DDKSPLIT
  171. #if DBG
  172. // Whistler bug 281090 detection code, print warning msg only, remove later
  173. vDetectMixedMIPLevels(lpcsxd->lpDDSLcl);
  174. #endif
  175. //@@END_DDKSPLIT
  176. DBG_CB_EXIT(D3DCreateSurfaceEx,lpcsxd->ddRVal);
  177. return DDHAL_DRIVER_HANDLED;
  178. } // D3DCreateSurfaceEx
  179. //-----------------------------Public Routine----------------------------------
  180. //
  181. // D3DDestroyDDLocal
  182. //
  183. // D3dDestroyDDLocal destroys all the Direct3D surfaces previously created by
  184. // D3DCreateSurfaceEx that belong to the same given local DirectDraw object.
  185. //
  186. // All Direct3D drivers must support D3dDestroyDDLocal.
  187. // Direct3D calls D3dDestroyDDLocal when the application indicates that the
  188. // Direct3D context is no longer required and it will be destroyed along with
  189. // all surfaces associated to it. The association comes through the pointer to
  190. // the local DirectDraw object. The driver must free any memory that the
  191. // driver's D3dCreateSurfaceExDDK_D3dCreateSurfaceEx_GG callback allocated for
  192. // each surface if necessary. The driver should not destroy the DirectDraw
  193. // surfaces associated with these Direct3D surfaces; this is the application's
  194. // responsibility.
  195. //
  196. // Parameters
  197. //
  198. // lpdddd
  199. // Pointer to the DestroyLocalDD structure that contains the
  200. // information required for the driver to destroy the surfaces.
  201. //
  202. // dwFlags
  203. // Currently unused
  204. // pDDLcl
  205. // Pointer to the local Direct Draw object which serves as a
  206. // reference for all the D3D surfaces that have to be
  207. // destroyed.
  208. // ddRVal
  209. // Specifies the location in which the driver writes the
  210. // return value of D3dDestroyDDLocal. A return code of DD_OK
  211. // indicates success.
  212. //
  213. // Return Value
  214. //
  215. // DDHAL_DRIVER_HANDLED
  216. // DDHAL_DRIVER_NOTHANDLED
  217. //-----------------------------------------------------------------------------
  218. DWORD CALLBACK
  219. D3DDestroyDDLocal(
  220. LPDDHAL_DESTROYDDLOCALDATA pddl)
  221. {
  222. P3_THUNKEDDATA *pThisDisplay;
  223. GET_THUNKEDDATA(pThisDisplay, pddl->pDDLcl->lpGbl);
  224. DBG_CB_ENTRY(D3DDestroyDDLocal);
  225. // Removing this entry from the hash table will cause the data destroy
  226. // callback to be called, which will in turn free all of the texture
  227. // structures that were allocated for this LCL
  228. HT_RemoveEntry(pThisDisplay->pDirectDrawLocalsHashTable,
  229. (ULONG_PTR)pddl->pDDLcl,
  230. pThisDisplay);
  231. pddl->ddRVal = DD_OK;
  232. DBG_CB_EXIT(D3DDestroyDDLocal, DDHAL_DRIVER_HANDLED);
  233. return DDHAL_DRIVER_HANDLED;
  234. } // D3DDestroyDDLocal
  235. //-----------------------------------------------------------------------------
  236. //
  237. //-----------------------------------------------------------------------------
  238. HRESULT
  239. _D3D_SU_SurfInternalSetDataRecursive(
  240. P3_THUNKEDDATA* pThisDisplay,
  241. PointerArray* pSurfaceArray,
  242. LPDDRAWI_DIRECTDRAW_LCL pDDLcl,
  243. LPDDRAWI_DDRAWSURFACE_LCL pRootDDSurfLcl,
  244. LPDDRAWI_DDRAWSURFACE_LCL pCurDDSurfLcl)
  245. {
  246. P3_SURF_INTERNAL* pSurfInternal;
  247. DWORD dwSurfaceHandle;
  248. LPATTACHLIST pCurAttachList;
  249. HRESULT hRes;
  250. DBG_CB_ENTRY(_D3D_SU_SurfInternalSetDataRecursive);
  251. dwSurfaceHandle = (DWORD)pCurDDSurfLcl->lpSurfMore->dwSurfaceHandle;
  252. #if DBG
  253. DISPDBG((DBGLVL, "D3DCreateSuraceEx Handle = %d fpVidMem = 0x%x (%s)",
  254. dwSurfaceHandle,
  255. pCurDDSurfLcl->lpGbl->fpVidMem,
  256. pcSimpleCapsString(pCurDDSurfLcl->ddsCaps.dwCaps)));
  257. #endif
  258. DBGDUMP_DDRAWSURFACE_LCL(10, pCurDDSurfLcl);
  259. // If this surface doesn't have a handle, return safely
  260. if (! dwSurfaceHandle)
  261. {
  262. return (DD_OK);
  263. }
  264. DISPDBG((DBGLVL,"Surface has a valid handle. Setting it up"));
  265. // Get the texture from within the surface array
  266. pSurfInternal = PA_GetEntry(pSurfaceArray, dwSurfaceHandle);
  267. // If we didn't find the texture, create one
  268. if (! pSurfInternal)
  269. {
  270. DISPDBG((DBGLVL,"Creating new internal surface for handle: 0x%x",
  271. dwSurfaceHandle));
  272. // Allocate the texture data space, because it hasn't
  273. // been done already
  274. pSurfInternal = (P3_SURF_INTERNAL*)HEAP_ALLOC(HEAP_ZERO_MEMORY,
  275. sizeof(P3_SURF_INTERNAL),
  276. ALLOC_TAG_DX(A));
  277. if (pSurfInternal == NULL)
  278. {
  279. DISPDBG((ERRLVL,"ERROR: Couldn't allocate surface "
  280. "internal data mem"));
  281. DBG_CB_EXIT(_D3D_SU_SurfInternalSetDataRecursive,
  282. DDERR_OUTOFMEMORY);
  283. return (DDERR_OUTOFMEMORY);
  284. }
  285. }
  286. else
  287. {
  288. DISPDBG((DBGLVL,"Surface handle re-used: 0x%x",
  289. dwSurfaceHandle));
  290. }
  291. // Add this texture to the surface list
  292. if (! PA_SetEntry(pSurfaceArray, dwSurfaceHandle, pSurfInternal))
  293. {
  294. return (DDERR_OUTOFMEMORY);
  295. }
  296. // Setup the surface structure
  297. _D3D_SU_SurfInternalSetData(pThisDisplay,
  298. pSurfInternal,
  299. pCurDDSurfLcl,
  300. dwSurfaceHandle);
  301. // Keep a pointer to the DD_DIRECTDRAW_LOCAL in order to
  302. // update colorkeying in DDSetColorKey possible. Notice
  303. // this is stored in DD_SURFACE_LOCAL.dwReserved1 as
  304. // DD_SURFACE_GLOBAL.dwReserved1 is being used for other
  305. // purpouses
  306. pCurDDSurfLcl->dwReserved1 = (ULONG_PTR)pDDLcl;
  307. // Don't need a seperate handle for mipmaps
  308. // or cubemaps as they are atomic in DX7.
  309. if ((pCurDDSurfLcl->ddsCaps.dwCaps & DDSCAPS_MIPMAP) ||
  310. (pCurDDSurfLcl->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_CUBEMAP))
  311. {
  312. return (DD_OK);
  313. }
  314. pCurAttachList = pCurDDSurfLcl->lpAttachList;
  315. // Simple surface, mission accomplished
  316. if (! pCurAttachList)
  317. {
  318. return (DD_OK);
  319. }
  320. // This recursion is usually needed for complex flipping chains
  321. pCurDDSurfLcl = pCurAttachList->lpAttached;
  322. if (pCurDDSurfLcl && (pCurDDSurfLcl != pRootDDSurfLcl))
  323. {
  324. hRes = _D3D_SU_SurfInternalSetDataRecursive(pThisDisplay,
  325. pSurfaceArray,
  326. pDDLcl,
  327. pRootDDSurfLcl,
  328. pCurDDSurfLcl);
  329. if (FAILED(hRes))
  330. {
  331. return (hRes);
  332. }
  333. }
  334. // This part will normally be enterned when stereo mode is on
  335. if (pCurAttachList->lpLink)
  336. {
  337. pCurDDSurfLcl = pCurAttachList->lpLink->lpAttached;
  338. if (pCurDDSurfLcl && (pCurDDSurfLcl != pRootDDSurfLcl))
  339. {
  340. hRes = _D3D_SU_SurfInternalSetDataRecursive(pThisDisplay,
  341. pSurfaceArray,
  342. pDDLcl,
  343. pRootDDSurfLcl,
  344. pCurDDSurfLcl);
  345. if (FAILED(hRes))
  346. {
  347. return (hRes);
  348. }
  349. }
  350. }
  351. return (DD_OK);
  352. }
  353. //-----------------------------------------------------------------------------
  354. //
  355. // _D3D_SU_SurfInternalSetMipMapLevelData
  356. //
  357. // Records the a LOD level and all associated information so that the chip
  358. // can use it later.
  359. //
  360. // Notice that ONLY while the D3DCreateSurfaceEx call is being made is the
  361. // LPDDRAWI_DDRAWSURFACE_LCL/PDD_LOCAL_SURFACE structure valid (Win9x/Win2K)
  362. // so we cannot just cache a pointer to it for later use.
  363. //
  364. //-----------------------------------------------------------------------------
  365. void
  366. _D3D_SU_SurfInternalSetMipMapLevelData(
  367. P3_THUNKEDDATA *pThisDisplay,
  368. P3_SURF_INTERNAL* pTexture,
  369. LPDDRAWI_DDRAWSURFACE_LCL pSurf,
  370. int LOD)
  371. {
  372. ASSERTDD(pSurf != NULL, "ERROR: NULL surface!");
  373. DISPDBG((6,"Storing LOD: %d, Pitch: %d, Width: %d",
  374. LOD, pSurf->lpGbl->lPitch, pSurf->lpGbl->wWidth));
  375. // Get the byte offset to the texture map from the base of video
  376. // memory or as a physical mem address (for AGP surfaces). This
  377. // cases will be taken care of by DDSurf_SurfaceOffsetFromMemoryBase.
  378. pTexture->MipLevels[LOD].dwOffsetFromMemoryBase =
  379. DDSurf_SurfaceOffsetFromMemoryBase(pThisDisplay, pSurf);
  380. // Store the DD surface's fpVidMem ptr
  381. pTexture->MipLevels[LOD].fpVidMem = pSurf->lpGbl->fpVidMem;
  382. // The TextureMapWidth hardware register holds width, layout, border and
  383. // AGP settings, and we will create an instance for each miplevel we'll use
  384. // Store the layout for this texture map
  385. // (linear layout is always used in this driver, we don't use patched surfs)
  386. pTexture->MipLevels[LOD].P3RXTextureMapWidth.Layout = P3RX_LAYOUT_LINEAR;
  387. // Store the pitch for this texture map level
  388. pTexture->MipLevels[LOD].P3RXTextureMapWidth.Width =
  389. DDSurf_GetPixelPitch(pSurf);
  390. // Store the DD surface's lPitch
  391. pTexture->MipLevels[LOD].lPitch = pSurf->lpGbl->lPitch;
  392. // Store AGP settings for this texture map
  393. if( pSurf->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM )
  394. pTexture->MipLevels[LOD].P3RXTextureMapWidth.HostTexture = 1;
  395. else
  396. pTexture->MipLevels[LOD].P3RXTextureMapWidth.HostTexture = 0;
  397. // Store mip level size
  398. pTexture->MipLevels[LOD].wWidth = (int)pSurf->lpGbl->wWidth;
  399. pTexture->MipLevels[LOD].wHeight = (int)pSurf->lpGbl->wHeight;
  400. pTexture->MipLevels[LOD].logWidth = log2((int)pSurf->lpGbl->wWidth);
  401. pTexture->MipLevels[LOD].logHeight = log2((int)pSurf->lpGbl->wHeight);
  402. } // _D3D_SU_SurfInternalSetMipMapLevelData
  403. //-----------------------------------------------------------------------------
  404. //
  405. // _D3D_SU_SurfInternalSetData
  406. //
  407. // Sets up all the necessary data for an internal surface structure.
  408. //
  409. //-----------------------------------------------------------------------------
  410. BOOL
  411. _D3D_SU_SurfInternalSetData(
  412. P3_THUNKEDDATA *pThisDisplay,
  413. P3_SURF_INTERNAL *pSurface,
  414. LPDDRAWI_DDRAWSURFACE_LCL pDDSLcl,
  415. DWORD dwSurfaceHandle)
  416. {
  417. DBG_ENTRY(_D3D_SU_SurfInternalSetData);
  418. // Store the pointer to the texture in the structure
  419. pSurface->pFormatSurface = _DD_SUR_GetSurfaceFormat(pDDSLcl);
  420. DBGDUMP_DDRAWSURFACE_LCL(DBGLVL, pDDSLcl);
  421. // Initially no LUT
  422. pSurface->dwLUTOffset = 0;
  423. // Need to remember the sizes and the log of the sizes of the maps
  424. pSurface->wWidth = (WORD)(pDDSLcl->lpGbl->wWidth);
  425. pSurface->wHeight = (WORD)(pDDSLcl->lpGbl->wHeight);
  426. pSurface->fArea = (float)pSurface->wWidth * (float)pSurface->wHeight;
  427. pSurface->logWidth = log2((int)pDDSLcl->lpGbl->wWidth);
  428. pSurface->logHeight = log2((int)pDDSLcl->lpGbl->wHeight);
  429. // Store the pointer to surface memory
  430. pSurface->fpVidMem = pDDSLcl->lpGbl->fpVidMem;
  431. // Magic number for validity check
  432. pSurface->MagicNo = SURF_MAGIC_NO;
  433. // This value is used if the texture turns out to be agp
  434. pSurface->dwGARTDevLast = pThisDisplay->dwGARTDev;
  435. // For AGP and correct rendering we need to know where the surface is stored
  436. if(pDDSLcl->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
  437. {
  438. if (pDDSLcl->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
  439. {
  440. DISPDBG((DBGLVL," Surface %d is in AGP Memory",dwSurfaceHandle));
  441. pSurface->Location = AGPMemory;
  442. }
  443. else
  444. {
  445. DISPDBG((DBGLVL," Surface %d is in Video Memory",dwSurfaceHandle));
  446. pSurface->Location = VideoMemory;
  447. }
  448. }
  449. else
  450. {
  451. DISPDBG((DBGLVL," Surface %d is in system memory - "
  452. "disabling use for rendering", dwSurfaceHandle));
  453. pSurface->Location = SystemMemory;
  454. }
  455. // Store caps & other DD fields for later
  456. pSurface->ddsCapsInt = pDDSLcl->ddsCaps;
  457. pSurface->dwFlagsInt = pDDSLcl->dwFlags;
  458. pSurface->dwCKLow = pDDSLcl->ddckCKSrcBlt.dwColorSpaceLowValue;
  459. pSurface->dwCKHigh = pDDSLcl->ddckCKSrcBlt.dwColorSpaceHighValue;
  460. pSurface->pixFmt = *DDSurf_GetPixelFormat(pDDSLcl);
  461. pSurface->dwPixelSize = DDSurf_GetChipPixelSize(pDDSLcl);
  462. pSurface->dwPixelPitch = DDSurf_GetPixelPitch(pDDSLcl);
  463. pSurface->dwPatchMode = P3RX_LAYOUT_LINEAR;
  464. pSurface->lOffsetFromMemoryBase = DDSurf_SurfaceOffsetFromMemoryBase(pThisDisplay, pDDSLcl);
  465. pSurface->lPitch = pDDSLcl->lpGbl->lPitch;
  466. pSurface->dwBitDepth = DDSurf_BitDepth(pDDSLcl);
  467. #if DX7_TEXMANAGEMENT
  468. _D3D_TM_InitSurfData(pSurface, pDDSLcl);
  469. #endif
  470. #if DX8_MULTISAMPLING
  471. pSurface->dwSampling =
  472. (pDDSLcl->lpSurfMore->ddsCapsEx.dwCaps3 & DDSCAPS3_MULTISAMPLE_MASK );
  473. #endif // DX8_MULTISAMPLING
  474. // Additional surface setup if it is a texture
  475. if (pDDSLcl->ddsCaps.dwCaps & DDSCAPS_TEXTURE )
  476. {
  477. LPDDRAWI_DDRAWSURFACE_LCL lpNextSurf;
  478. int iLOD;
  479. lpNextSurf = pDDSLcl;
  480. iLOD = 0;
  481. #if DX8_3DTEXTURES
  482. if ((pDDSLcl->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_VOLUME) &&
  483. (pSurface->dwBitDepth != 0))
  484. {
  485. // Mark this texture as 3D texture.
  486. pSurface->b3DTexture = TRUE;
  487. pSurface->wDepth = LOWORD(pDDSLcl->lpSurfMore->ddsCapsEx.dwCaps4);
  488. pSurface->logDepth = log2((int)pSurface->wDepth);
  489. pSurface->dwSlice = pDDSLcl->lpGbl->dwBlockSizeY;
  490. pSurface->dwSliceInTexel = pDDSLcl->lpGbl->dwBlockSizeY /
  491. (DDSurf_BitDepth(pDDSLcl) / 8);
  492. }
  493. else
  494. {
  495. // Not a 3D texture
  496. pSurface->b3DTexture = FALSE;
  497. pSurface->wDepth = 0;
  498. pSurface->logDepth = 0;
  499. pSurface->dwSlice = 0;
  500. pSurface->dwSliceInTexel = 0;
  501. }
  502. #endif // DX8_3DTEXTURES
  503. // For Permedia the texture offset is in pixels.
  504. // Store the offsets for each of the mipmap levels
  505. if (pDDSLcl->ddsCaps.dwCaps & DDSCAPS_MIPMAP)
  506. {
  507. BOOL bMoreSurfaces = TRUE;
  508. pSurface->bMipMap = TRUE;
  509. // Walk the chain of surfaces and find all of the mipmap levels
  510. do
  511. {
  512. DISPDBG((DBGLVL, "Loading texture iLOD:%d, Ptr:0x%x",
  513. iLOD, lpNextSurf->lpGbl->fpVidMem));
  514. _D3D_SU_SurfInternalSetMipMapLevelData(pThisDisplay,
  515. pSurface,
  516. lpNextSurf,
  517. iLOD);
  518. // Is there another surface in the chain?
  519. if (lpNextSurf->lpAttachList)
  520. lpNextSurf = lpNextSurf->lpAttachList->lpAttached;
  521. else
  522. bMoreSurfaces = FALSE;
  523. iLOD++;
  524. }
  525. while( bMoreSurfaces );
  526. // This isn't really a MipMap if iLOD is 1
  527. if (iLOD == 1)
  528. {
  529. DISPDBG((DBGLVL, "Texture was not a mipmap - only 1 level"));
  530. pSurface->bMipMap = FALSE;
  531. }
  532. pSurface->iMipLevels = iLOD;
  533. }
  534. else // NOT A MIPMAP, simply store away the offset
  535. {
  536. pSurface->bMipMap = FALSE;
  537. pSurface->iMipLevels = 1;
  538. _D3D_SU_SurfInternalSetMipMapLevelData(pThisDisplay,
  539. pSurface,
  540. lpNextSurf,
  541. iLOD);
  542. }
  543. } // if (pDDSLcl->ddsCaps.dwCaps & DDSCAPS_TEXTURE )
  544. #if DX7_PALETTETEXTURE
  545. // Initialize the palette handle and flags
  546. pSurface->dwPaletteHandle = 0;
  547. pSurface->dwPaletteFlags = 0;
  548. #endif
  549. DBG_EXIT(_D3D_SU_SurfInternalSetData, TRUE);
  550. return TRUE;
  551. } // _D3D_SU_SurfInternalSetData
  552. //-----------------------------------------------------------------------------
  553. //
  554. // _D3D_SU_SurfaceArrayDestroyCallback
  555. //
  556. // Called when a surface is removed from the pointer array associated with a
  557. // DirectDraw local. Simply frees the memory
  558. //-----------------------------------------------------------------------------
  559. void
  560. _D3D_SU_SurfaceArrayDestroyCallback(
  561. PointerArray* pArray,
  562. void* pData,
  563. void* pExtra)
  564. {
  565. P3_SURF_INTERNAL* pTexture = (P3_SURF_INTERNAL*)pData;
  566. P3_THUNKEDDATA *pThisDisplay = (P3_THUNKEDDATA*)pExtra;
  567. DBG_ENTRY(_D3D_SU_SurfaceArrayDestroyCallback);
  568. #if DX7_TEXMANAGEMENT
  569. if (pTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
  570. {
  571. _D3D_TM_RemoveTexture(pThisDisplay, pTexture);
  572. }
  573. #endif
  574. // Simply free the data
  575. HEAP_FREE(pData);
  576. DBG_EXIT(_D3D_SU_SurfaceArrayDestroyCallback, TRUE);
  577. } // _D3D_SU_SurfaceArrayDestroyCallback
  578. //-----------------------------------------------------------------------------
  579. //
  580. // _D3D_SU_DirectDrawLocalDestroyCallback
  581. //
  582. // Called when a directdraw local is removed from the hash table.
  583. // We use the pointer associated with it to free the pointer array that
  584. // was created.
  585. //
  586. //-----------------------------------------------------------------------------
  587. void
  588. _D3D_SU_DirectDrawLocalDestroyCallback(
  589. HashTable* pTable,
  590. void* pData,
  591. void* pExtra)
  592. {
  593. PointerArray* pPointerArray = (PointerArray*)pData;
  594. DBG_ENTRY(_D3D_SU_DirectDrawLocalDestroyCallback);
  595. if (pPointerArray)
  596. {
  597. DISPDBG((DBGLVL, "Destroying an array of surface pointers for this "
  598. "LCL ddraw object"));
  599. // The data hanging off the local object is a pointerarray.
  600. // Calling destory will cause it to free the data items through the
  601. // callback if one is registered.
  602. PA_DestroyArray(pPointerArray, pExtra);
  603. }
  604. DBG_EXIT(_D3D_SU_DirectDrawLocalDestroyCallback, TRUE);
  605. } // _D3D_SU_DirectDrawLocalDestroyCallback
  606. #if DX7_PALETTETEXTURE
  607. //-----------------------------------------------------------------------------
  608. //
  609. // _D3D_SU_PaletteArrayDestroyCallback
  610. //
  611. // Called when a palette is removed from the pointer array.
  612. // Simply frees the memory
  613. //-----------------------------------------------------------------------------
  614. void
  615. _D3D_SU_PaletteArrayDestroyCallback(
  616. PointerArray* pArray,
  617. void* pData,
  618. void* pExtra)
  619. {
  620. DBG_ENTRY(_D3D_SU_PaletteArrayDestroyCallback);
  621. // Simply free the data
  622. HEAP_FREE(pData);
  623. DBG_EXIT(_D3D_SU_PaletteArrayDestroyCallback, TRUE);
  624. } // _D3D_SU_PaletteArrayDestroyCallback
  625. #endif // DX7_PALETTESURFACE
  626. //-----------------------------------------------------------------------------
  627. //
  628. // _D3D_SU_DumpSurfInternal
  629. //
  630. // Dumps into the debugger the drivers private data structure for the surface
  631. //
  632. //-----------------------------------------------------------------------------
  633. void
  634. _D3D_SU_DumpSurfInternal(
  635. DWORD lvl,
  636. char *psHeader,
  637. P3_SURF_INTERNAL *pSurface)
  638. {
  639. int i;
  640. DISPDBG((lvl,"Dumping %s surface @ %x",psHeader,pSurface));
  641. DISPDBG((lvl," MagicNo = 0x%x",pSurface->MagicNo));
  642. DISPDBG((lvl," pFormatSurface = 0x%x",pSurface->pFormatSurface)); // P3_SURF_FORMAT* pFormatSurface;
  643. DISPDBG((lvl," Location = %d",pSurface->Location));
  644. DISPDBG((lvl," dwLUTOffset = 0x%x",pSurface->dwLUTOffset));
  645. DISPDBG((lvl," dwGARTDevLast = 0x%x",pSurface->dwGARTDevLast));
  646. DISPDBG((lvl," wWidth = %d",(LONG)pSurface->wWidth));
  647. DISPDBG((lvl," wHeight = %d",(LONG)pSurface->wHeight));
  648. DISPDBG((lvl," logWidth = %d",pSurface->logWidth));
  649. DISPDBG((lvl," logHeight = %d",pSurface->logHeight));
  650. DISPDBG((lvl," fArea = 0x%x",*(DWORD *)&pSurface->fArea));
  651. // DDSCAPS ddsCapsInt;
  652. DISPDBG((lvl," dwFlagsInt = 0x%x",pSurface->dwFlagsInt));
  653. DISPDBG((lvl," dwCKLow = 0x%x",pSurface->dwCKLow));
  654. DISPDBG((lvl," dwCKHigh = 0x%x",pSurface->dwCKHigh));
  655. // DDPIXELFORMAT pixFmt;
  656. DISPDBG((lvl," dwPixelSize = 0x%x",pSurface->dwPixelSize));
  657. DISPDBG((lvl," dwPixelPitch = 0x%x",pSurface->dwPixelPitch));
  658. DISPDBG((lvl," dwPatchMode = 0x%x",pSurface->dwPatchMode));
  659. DISPDBG((lvl," lPitch = 0x%x",pSurface->lPitch));
  660. DISPDBG((lvl," fpVidMem = 0x%x",pSurface->fpVidMem));
  661. #if DX8_3DTEXTURES
  662. DISPDBG((lvl," b3DTexture = 0x%x",pSurface->b3DTexture));
  663. DISPDBG((lvl," wDepth = %d",(LONG)pSurface->wDepth));
  664. #endif // DX8_3DTEXTURES
  665. DISPDBG((lvl," bMipMap = 0x%x",pSurface->bMipMap));
  666. DISPDBG((lvl," iMipLevels = %d",pSurface->iMipLevels));
  667. for (i = 0; i < pSurface->iMipLevels; i++)
  668. {
  669. DISPDBG((lvl," MipLevels[%d].logWidth = 0x%x",
  670. i,pSurface->MipLevels[i].logWidth));
  671. DISPDBG((lvl," MipLevels[%d].logHeight = 0x%x",
  672. i,pSurface->MipLevels[i].logHeight));
  673. DISPDBG((lvl," MipLevels[%d].dwOffsetFromMemoryBase = 0x%x",
  674. i,pSurface->MipLevels[i].dwOffsetFromMemoryBase));
  675. DISPDBG((lvl," MipLevels[%d].fpVidMem = 0x%x",
  676. i,pSurface->MipLevels[i].fpVidMem));
  677. DISPDBG((lvl," MipLevels[%d].lPitch = 0x%x",
  678. i,pSurface->MipLevels[i].lPitch));
  679. DISPDBG((lvl," MipLevels[%d].P3RXTextureMapWidth = 0x%x",
  680. i,*(DWORD*)(&pSurface->MipLevels[i].P3RXTextureMapWidth)));
  681. }
  682. } // _D3D_SU_DumpSurfInternal