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.

2333 lines
91 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * D3D SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: d3d.c
  8. *
  9. * Content: Main context and texture management callbacks for D3D
  10. *
  11. * Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "precomp.h"
  15. #include "d3dhw.h"
  16. #include "d3dcntxt.h"
  17. #include "d3ddelta.h"
  18. #include "d3dtxman.h"
  19. #define ALLOC_TAG ALLOC_TAG_3D2P
  20. BOOL D3DInitialised = FALSE;
  21. //-----------------------------Public Routine----------------------------------
  22. //
  23. // DWORD D3DContextCreate
  24. //
  25. // The ContextCreate callback is invoked when a new Direct3D device is being
  26. // created by a Direct3D application. The driver is required to generate a
  27. // unique context id for this new context. Direct3D will then use this context
  28. // id in every subsequent callback invocation for this Direct3D device.
  29. //
  30. // Context is the current rasterization state. For instance, if there are 3
  31. // applications running, each will have a different state at any point in time.
  32. // When each one is running, the hardware has to make sure that the context,
  33. // (whether doing Gouraud shading, for example) is the same as the last time
  34. // that application got a time slice.
  35. //
  36. // State is anything that the particular device needs to know per context
  37. // i.e. what surface is being rendered to, shading, texture, texture handles,
  38. // what physical surfaces those texture handles represent, etc. The context
  39. // encapsulates all state for the Direct3D device - state is not shared
  40. // between contexts. Therefore the driver needs to maintain full state
  41. // information for each context. This state will be changed by calls to the
  42. // RenderState callback. In the case of rasterization only hardware, the
  43. // driver need only maintain rasterization state. As well as state, the driver
  44. // will also want to store the lpDDS, lpDDSZ, and dwPid from the callback
  45. // data argument.
  46. //
  47. // The driver should not create a context handle of zero. This is guaranteed
  48. // to be an invalid context handle.
  49. //
  50. // Parameters
  51. // pccd
  52. // Pointer to a structure containing things including the current
  53. // rendering surface, the current Z surface, and the DirectX object
  54. // handle, etc.
  55. //
  56. // .lpDDGbl
  57. // Points to the DirectDraw structure representing the
  58. // DirectDraw object.
  59. // .lpDDLcl(replaces lpDDGbl in DX7)
  60. // Points to the DirectDraw structure representing the
  61. // DirectDraw object.
  62. // .lpDDS
  63. // This is the surface that is to be used as the rendering
  64. // target, i.e., the 3D accelerator sprays its bits at this
  65. // surface.
  66. // .lpDDSZ
  67. // The surface that is to be used as the Z buffer. If this
  68. // is NULL, no Z buffering is to be performed.
  69. // .dwPid
  70. // The process id of the Direct3D application that initiated
  71. // the creation of the Direct3D device.
  72. // .dwhContext
  73. // The driver should place the context ID that it wants Direct3D
  74. // to use when communicating with the driver. This should be
  75. // unique.
  76. // .ddrval
  77. // Return code. DD_OK indicates success.
  78. //
  79. // Return Value
  80. // Returns one of the following values:
  81. // DDHAL_DRIVER_HANDLED
  82. // DDHAL_DRIVER_NOTHANDLED
  83. //
  84. //-----------------------------------------------------------------------------
  85. TextureCacheManager P2TextureManager;
  86. DWORD P2TMcount = 0;
  87. DWORD CALLBACK
  88. D3DContextCreate(LPD3DHAL_CONTEXTCREATEDATA pccd)
  89. {
  90. PERMEDIA_D3DCONTEXT* pContext;
  91. PermediaSurfaceData* pPrivateData;
  92. DWORD dwSlotNum;
  93. LPDDRAWI_DIRECTDRAW_GBL lpDDGbl=pccd->lpDDLcl->lpGbl;
  94. // Remember the global data for this context.
  95. PPDev ppdev = (PPDev)lpDDGbl->dhpdev;
  96. PERMEDIA_DEFS(ppdev);
  97. DBG_D3D((6,"Entering D3DContextCreate"));
  98. // Find an empty slot in the global D3D context table
  99. for (dwSlotNum = 1; dwSlotNum < MAX_CONTEXT_NUM; dwSlotNum++)
  100. {
  101. if (ContextSlots[dwSlotNum] == 0)
  102. break;
  103. }
  104. // return if we have no contexts left
  105. if (dwSlotNum == MAX_CONTEXT_NUM)
  106. {
  107. pccd->ddrval = D3DHAL_OUTOFCONTEXTS;
  108. return (DDHAL_DRIVER_HANDLED);
  109. }
  110. // Now allocate the drivers D3D context memory. Simply a chunk of
  111. // RAM with the relevent data in it.
  112. pContext = (PERMEDIA_D3DCONTEXT *)
  113. ENGALLOCMEM( FL_ZERO_MEMORY, sizeof(PERMEDIA_D3DCONTEXT), ALLOC_TAG);
  114. if (pContext == NULL)
  115. {
  116. DBG_D3D((0,"ERROR: Couldn't allocate Context mem"));
  117. pccd->ddrval = DDERR_OUTOFMEMORY;
  118. return (DDHAL_DRIVER_HANDLED);
  119. }
  120. else
  121. {
  122. DBG_D3D((4,"Allocated Context Mem"));
  123. memset((void *)pContext, 0, sizeof(PERMEDIA_D3DCONTEXT));
  124. }
  125. // Setup the drivers's D3D context
  126. pContext->Hdr.pSelf = (UINT_PTR)pContext;
  127. // Set up the DRIVER rendering context structure for sanity checks
  128. pContext->Hdr.MagicNo = RC_MAGIC_NO;
  129. // Remember the card we are running on
  130. pContext->ppdev = ppdev;
  131. // Set context handle in driver's D3D context
  132. pccd->dwhContext = dwSlotNum; //out:Context handle
  133. ContextSlots[dwSlotNum] = (UINT_PTR)pContext;
  134. DBG_D3D((4,"Allocated Direct3D context: 0x%x",pccd->dwhContext));
  135. // Allocate a register context
  136. P2CtxtPtr pP2ctxt;
  137. pP2ctxt = P2AllocateNewContext( pContext->ppdev, NULL, 0, P2CtxtWriteOnly);
  138. if (pP2ctxt == NULL)
  139. {
  140. DBG_D3D((0,"ERROR: Couldn't allocate Register Context"));
  141. CleanDirect3DContext(pContext, pccd->dwhContext);
  142. pccd->ddrval = DDERR_OUTOFMEMORY;
  143. return (DDHAL_DRIVER_HANDLED);
  144. }
  145. else
  146. {
  147. DBG_D3D((4,"Allocated Register context: 0x%x",pP2ctxt));
  148. // Record the register context in the window render context
  149. pContext->hPermediaContext = pP2ctxt;
  150. }
  151. // No texture at present
  152. pContext->CurrentTextureHandle = 0;
  153. // Initialize texture management for this context
  154. if (0 == P2TMcount)
  155. {
  156. if ( FAILED(TextureCacheManagerInitialize(&P2TextureManager)) )
  157. {
  158. DBG_D3D((0,"ERROR: Couldn't initialize TextureCacheManager"));
  159. CleanDirect3DContext(pContext, pccd->dwhContext);
  160. pccd->ddrval = DDERR_OUTOFMEMORY;
  161. return (DDHAL_DRIVER_HANDLED);
  162. }
  163. }
  164. P2TMcount++;
  165. pContext->pTextureManager = &P2TextureManager;
  166. // Remember the local DD object and get the
  167. // correct array of surfaces for this context
  168. pContext->pDDLcl = pccd->lpDDLcl;
  169. pContext->pHandleList = GetSurfaceHandleList(pccd->lpDDLcl);
  170. if (pContext->pHandleList == NULL)
  171. {
  172. DBG_D3D((0,"ERROR: Couldn't get a surface handle for lpDDLcl"));
  173. CleanDirect3DContext(pContext, pccd->dwhContext);
  174. pccd->ddrval = DDERR_OUTOFMEMORY;
  175. return (DDHAL_DRIVER_HANDLED);
  176. }
  177. DBG_D3D((4,"Getting pHandleList=%08lx for pDDLcl %08lx",
  178. pContext->pHandleList,pccd->dwPID));
  179. pContext->RenderSurfaceHandle = DDS_LCL(pccd->lpDDS)->lpSurfMore->dwSurfaceHandle;
  180. if (NULL != pccd->lpDDSZ)
  181. pContext->ZBufferHandle = DDS_LCL(pccd->lpDDSZ)->lpSurfMore->dwSurfaceHandle;
  182. else
  183. pContext->ZBufferHandle = 0;
  184. // Now write the default setup to the chip.
  185. if ( FAILED(InitPermediaContext(pContext)) )
  186. {
  187. DBG_D3D((0,"ERROR: D3DContextCreate receives bad parameters "));
  188. CleanDirect3DContext(pContext, pccd->dwhContext);
  189. pccd->ddrval = D3DHAL_CONTEXT_BAD;
  190. return (DDHAL_DRIVER_HANDLED);
  191. }
  192. // ---------------- Setup default states in driver ------------------------
  193. // On context creation, no render states are overridden
  194. STATESET_INIT(pContext->overrides);
  195. #if D3D_STATEBLOCKS
  196. // Default state block recording mode = no recording
  197. pContext->bStateRecMode = FALSE;
  198. pContext->pCurrSS = NULL;
  199. pContext->pIndexTableSS = NULL;
  200. pContext->dwMaxSSIndex = 0;
  201. #endif //D3D_STATEBLOCKS
  202. pContext->Hdr.Flags = CTXT_HAS_GOURAUD_ENABLED ;
  203. pContext->CullMode = D3DCULL_CCW;
  204. // Set the last alpha value to 16 to force a new
  205. // send of the flat stipple patterns.
  206. pContext->LastAlpha = 16;
  207. pContext->bKeptStipple = FALSE; // By default, stippling is off
  208. pContext->bCanChromaKey = FALSE; // Turn Chroma keying off by default
  209. pContext->LowerChromaColor = 0x0; // These are the default chromakey values
  210. pContext->UpperChromaColor = 0x0;
  211. pContext->FakeBlendNum = 0; // No need to emulate any blend mode
  212. //@@BEGIN_DDKSPLIT
  213. #if D3D_POINTSPRITES
  214. pContext->bPointSpriteEnabled = FALSE; // Point sprite defaults
  215. pContext->fPointSize = 1.0f;
  216. #endif // D3D_POINTSPRITES
  217. //@@END_DDKSPLIT
  218. // Initialise the RenderCommand. States will add to this
  219. pContext->RenderCommand = 0;
  220. RENDER_SUB_PIXEL_CORRECTION_ENABLE(pContext->RenderCommand);
  221. // Setup TSS defaults for stage 0
  222. pContext->TssStates[D3DTSS_TEXTUREMAP] = 0;
  223. pContext->TssStates[D3DTSS_COLOROP] = D3DTOP_MODULATE;
  224. pContext->TssStates[D3DTSS_ALPHAOP] = D3DTOP_SELECTARG1;
  225. pContext->TssStates[D3DTSS_COLORARG1] = D3DTA_TEXTURE;
  226. pContext->TssStates[D3DTSS_COLORARG2] = D3DTA_CURRENT;
  227. pContext->TssStates[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE;
  228. pContext->TssStates[D3DTSS_ALPHAARG2] = D3DTA_CURRENT;
  229. pContext->TssStates[D3DTSS_TEXCOORDINDEX] = 0;
  230. pContext->TssStates[D3DTSS_ADDRESS] = D3DTADDRESS_WRAP;
  231. pContext->TssStates[D3DTSS_ADDRESSU] = D3DTADDRESS_WRAP;
  232. pContext->TssStates[D3DTSS_ADDRESSV] = D3DTADDRESS_WRAP;
  233. pContext->TssStates[D3DTSS_MAGFILTER] = D3DTFG_POINT;
  234. pContext->TssStates[D3DTSS_MINFILTER] = D3DTFN_POINT;
  235. pContext->TssStates[D3DTSS_MIPFILTER] = D3DTFP_NONE;
  236. pContext->TssStates[D3DTSS_BUMPENVMAT00] = 0; // info we don't use
  237. pContext->TssStates[D3DTSS_BUMPENVMAT01] = 0; // in this sample
  238. pContext->TssStates[D3DTSS_BUMPENVMAT10] = 0;
  239. pContext->TssStates[D3DTSS_BUMPENVMAT11] = 0;
  240. pContext->TssStates[D3DTSS_BUMPENVLSCALE] = 0;
  241. pContext->TssStates[D3DTSS_BUMPENVLOFFSET] = 0;
  242. pContext->TssStates[D3DTSS_BORDERCOLOR] = 0x00000000;
  243. pContext->TssStates[D3DTSS_MAXMIPLEVEL] = 0;
  244. pContext->TssStates[D3DTSS_MAXANISOTROPY] = 1;
  245. // Force a change in texture before any
  246. // rendering takes place for this context
  247. DIRTY_TEXTURE;
  248. DBG_D3D((6,"Exiting D3DContextCreate"));
  249. pccd->ddrval = DD_OK;
  250. return (DDHAL_DRIVER_HANDLED);
  251. } // D3DContextCreate
  252. //-----------------------------Public Routine----------------------------------
  253. //
  254. // DWORD D3DContextDestroy
  255. //
  256. // This callback is invoked when a Direct3D Device is being destroyed. As each
  257. // device is represented by a context ID, the driver is passed a context to
  258. // destroy.
  259. //
  260. // The driver should free all resources it allocated to the context being
  261. // deleted. For example, the driver should free any texture resources it
  262. // associated with the context. The driver should not free the DirectDraw
  263. // surface(s) associated with the context because these will be freed by
  264. // DirectDraw in response to an application or Direct3D runtime request.
  265. //
  266. // Parameters
  267. // pcdd
  268. // Pointer to Context destroy information.
  269. //
  270. // .dwhContext
  271. // The ID of the context to be destroyed.
  272. // .ddrval
  273. // Return code. DD_OK indicates success.
  274. //
  275. // Return Value
  276. // Returns one of the following values:
  277. // DDHAL_DRIVER_HANDLED
  278. // DDHAL_DRIVER_NOTHANDLED
  279. //
  280. //-----------------------------------------------------------------------------
  281. DWORD CALLBACK
  282. D3DContextDestroy(LPD3DHAL_CONTEXTDESTROYDATA pcdd)
  283. {
  284. PERMEDIA_D3DCONTEXT *pContext;
  285. // Deleting context
  286. DBG_D3D((6,"Entering D3DContextDestroy, context = %08lx",pcdd->dwhContext));
  287. pContext = (PERMEDIA_D3DCONTEXT *)ContextSlots[pcdd->dwhContext] ;
  288. if ( pContext != NULL && pContext->Hdr.MagicNo == RC_MAGIC_DISABLE)
  289. // render context has been deliberately disabled.
  290. // set the magic number back to valid to allow the cleanup
  291. // to proceed in the normal way.
  292. pContext->Hdr.MagicNo = RC_MAGIC_NO ;
  293. CHK_CONTEXT( pContext, pcdd->ddrval, "D3DContextDestroy");
  294. DBG_D3D((4,"Freeing context resources"));
  295. CleanDirect3DContext(pContext, pcdd->dwhContext);
  296. pcdd->ddrval = DD_OK;
  297. DBG_D3D((6,"Exiting D3DContextDestroy"));
  298. return (DDHAL_DRIVER_HANDLED);
  299. } // D3DContextDestroy
  300. //-----------------------------------------------------------------------------
  301. //
  302. // void __InitD3DTextureWithDDSurfInfo
  303. //
  304. //-----------------------------------------------------------------------------
  305. void
  306. __InitD3DTextureWithDDSurfInfo(PPERMEDIA_D3DTEXTURE pTexture,
  307. LPDDRAWI_DDRAWSURFACE_LCL lpSurf,
  308. PPDev ppdev)
  309. {
  310. DBG_D3D((10,"Entering lpSurf=%08lx %08lx",lpSurf,lpSurf->lpGbl->fpVidMem));
  311. pTexture->pTextureSurface =
  312. (PermediaSurfaceData*)lpSurf->lpGbl->dwReserved1;
  313. if (NULL != pTexture->pTextureSurface)
  314. {
  315. pTexture->pTextureSurface->dwFlags |= P2_SURFACE_NEEDUPDATE;
  316. // need to recover this as CreateSurfaceEx may call us during TextureSwap()
  317. pTexture->dwPaletteHandle = pTexture->pTextureSurface->dwPaletteHandle;
  318. }
  319. // Need to remember the sizes and the log of the sizes of the maps
  320. pTexture->fpVidMem = lpSurf->lpGbl->fpVidMem;
  321. pTexture->lPitch = lpSurf->lpGbl->lPitch;
  322. pTexture->wWidth = (WORD)(lpSurf->lpGbl->wWidth);
  323. pTexture->wHeight = (WORD)(lpSurf->lpGbl->wHeight);
  324. pTexture->dwRGBBitCount=lpSurf->lpGbl->ddpfSurface.dwRGBBitCount;
  325. pTexture->m_dwBytes = pTexture->wHeight * pTexture->lPitch;
  326. // Magic number for validity check
  327. pTexture->MagicNo = TC_MAGIC_NO;
  328. pTexture->dwFlags = lpSurf->dwFlags;
  329. pTexture->dwCaps = lpSurf->ddsCaps.dwCaps;
  330. pTexture->dwCaps2= lpSurf->lpSurfMore->ddsCapsEx.dwCaps2;
  331. if (DDRAWISURF_HASCKEYSRCBLT & pTexture->dwFlags)
  332. {
  333. pTexture->dwKeyLow = lpSurf->ddckCKSrcBlt.dwColorSpaceLowValue;
  334. pTexture->dwKeyHigh = lpSurf->ddckCKSrcBlt.dwColorSpaceHighValue;
  335. DBG_D3D((4, "ColorKey exists (%08lx %08lx) on surface %d",
  336. pTexture->dwKeyLow,pTexture->dwKeyHigh,
  337. lpSurf->lpSurfMore->dwSurfaceHandle));
  338. }
  339. if (DD_P2AGPCAPABLE(ppdev) && pTexture->dwCaps & DDSCAPS_NONLOCALVIDMEM)
  340. {
  341. pTexture->lSurfaceOffset = DD_AGPSURFBASEOFFSET(lpSurf->lpGbl);
  342. }
  343. #if D3D_MIPMAPPING
  344. // Verify if texture has mip maps atteched
  345. if (lpSurf->ddsCaps.dwCaps & DDSCAPS_MIPMAP)
  346. {
  347. LPDDRAWI_DDRAWSURFACE_LCL lpNextSurf;
  348. int LOD;
  349. lpNextSurf = lpSurf;
  350. LOD = 0;
  351. pTexture->bMipMap = TRUE;
  352. // Calculate the number of mipmap levels (if this is a mipmap)
  353. pTexture->iMipLevels = (DWORD)((pTexture->wWidth > pTexture->wHeight) ?
  354. log2((int)pTexture->wWidth) :
  355. log2((int)pTexture->wHeight)) + 1;
  356. // Walk the chain of surfaces and find all of the mipmap levels
  357. for (LOD = 0; LOD < pTexture->iMipLevels; LOD++)
  358. {
  359. DBG_D3D((4, "Loading texture LOD:%d, Ptr:0x%x",
  360. LOD, lpNextSurf->lpGbl->fpVidMem));
  361. // Store the offsets for each of the mipmap levels
  362. StorePermediaLODLevel(ppdev, pTexture, lpNextSurf, LOD);
  363. // Is there another surface in the chain?
  364. if (lpNextSurf->lpAttachList)
  365. {
  366. lpNextSurf = lpNextSurf->lpAttachList->lpAttached;
  367. if (lpNextSurf == NULL)
  368. break;
  369. }
  370. else
  371. break;
  372. }
  373. // This isn't really a MipMap if LOD is 0
  374. if (LOD == 0)
  375. {
  376. DBG_D3D((4, "Texture was not a mipmap - only 1 level"));
  377. pTexture->bMipMap = FALSE;
  378. pTexture->iMipLevels = 1;
  379. }
  380. else
  381. {
  382. // Fill in the remaining levels with the smallest LOD
  383. // (this is for applications that haven't bothered to
  384. // pass us all of the LOD's).
  385. if (LOD < (pTexture->iMipLevels - 1))
  386. {
  387. int iLastLOD = LOD;
  388. DBG_D3D((4,"Filling in missing mipmaps!"));
  389. for (;LOD < MAX_MIP_LEVELS; LOD++)
  390. {
  391. pTexture->MipLevels[LOD] = pTexture->MipLevels[iLastLOD];
  392. }
  393. }
  394. }
  395. }
  396. else
  397. #endif //D3D_MIPMAPPING
  398. {
  399. // NOT A MIPMAP, simply store away the offset of level 0
  400. pTexture->bMipMap = FALSE;
  401. pTexture->iMipLevels = 1;
  402. StorePermediaLODLevel(ppdev, pTexture, lpSurf, 0);
  403. }
  404. // If debugging show what has just been created
  405. DISPTEXTURE((ppdev, pTexture, &lpSurf->lpGbl->ddpfSurface));
  406. DBG_D3D((10,"Exiting __InitD3DTextureWithDDSurfInfo"));
  407. } // __InitD3DTextureWithDDSurfInfo
  408. //@@BEGIN_DDKSPLIT
  409. #if MULTITHREADED
  410. //-----------------------------------------------------------------------------
  411. //
  412. // Multithread support wrappers for D3D callback functions
  413. //
  414. //-----------------------------------------------------------------------------
  415. //DWORD CALLBACK MtD3DContextCreate(LPD3DHAL_CONTEXTCREATEDATA pccd);
  416. WRAPMTDXCALLBACK(D3D, D3DContextCreate, LPD3DHAL_CONTEXTCREATEDATA, pccd,
  417. pccd->lpDDLcl->lpGbl->dhpdev)
  418. //DWORD CALLBACK MtD3DContextDestroy(LPD3DHAL_CONTEXTDESTROYDATA pcdd);
  419. WRAPMTDXCALLBACK(D3D, D3DContextDestroy, LPD3DHAL_CONTEXTDESTROYDATA, pcdd,
  420. ((PERMEDIA_D3DCONTEXT *)ContextSlots[pcdd->dwhContext])->ppdev)
  421. #endif MULTITHREADED
  422. //@@END_DDKSPLIT
  423. //-----------------------------------------------------------------------------
  424. // Direct3D HAL Table.
  425. //
  426. // This table contains all of the HAL calls that this driver supports in the
  427. // D3DHAL_Callbacks structure. These calls pertain to device context, scene
  428. // capture, execution, textures, transform, lighting, and pipeline state.
  429. // None of this is emulation code. The calls take the form of a return code
  430. // equal to: HalCall(HalCallData* lpData). All of the information in this
  431. // table will be implementation specific according to the specifications of
  432. // the hardware.
  433. //
  434. //-----------------------------------------------------------------------------
  435. #define PermediaTriCaps { \
  436. sizeof(D3DPRIMCAPS), \
  437. D3DPMISCCAPS_CULLCCW | /* miscCaps */ \
  438. D3DPMISCCAPS_CULLCW | \
  439. D3DPMISCCAPS_CULLNONE | \
  440. D3DPMISCCAPS_MASKPLANES | \
  441. D3DPMISCCAPS_MASKZ, \
  442. D3DPRASTERCAPS_DITHER | /* rasterCaps */ \
  443. D3DPRASTERCAPS_SUBPIXEL | \
  444. D3DPRASTERCAPS_ZTEST | \
  445. D3DPRASTERCAPS_FOGVERTEX | \
  446. D3DPRASTERCAPS_STIPPLE, \
  447. D3DPCMPCAPS_NEVER | \
  448. D3DPCMPCAPS_LESS | \
  449. D3DPCMPCAPS_EQUAL | \
  450. D3DPCMPCAPS_LESSEQUAL | \
  451. D3DPCMPCAPS_GREATER | \
  452. D3DPCMPCAPS_NOTEQUAL | \
  453. D3DPCMPCAPS_GREATEREQUAL | \
  454. D3DPCMPCAPS_ALWAYS | \
  455. D3DPCMPCAPS_LESSEQUAL, /* zCmpCaps */ \
  456. D3DPBLENDCAPS_SRCALPHA | /* sourceBlendCaps */ \
  457. D3DPBLENDCAPS_ONE, \
  458. D3DPBLENDCAPS_INVSRCALPHA | /* destBlendCaps */ \
  459. D3DPBLENDCAPS_ZERO | \
  460. D3DPBLENDCAPS_ONE, \
  461. 0, /* alphatestCaps */ \
  462. D3DPSHADECAPS_COLORFLATRGB| /* shadeCaps */ \
  463. D3DPSHADECAPS_COLORGOURAUDRGB | \
  464. D3DPSHADECAPS_SPECULARFLATRGB | \
  465. D3DPSHADECAPS_SPECULARGOURAUDRGB | \
  466. D3DPSHADECAPS_FOGFLAT | \
  467. D3DPSHADECAPS_FOGGOURAUD | \
  468. D3DPSHADECAPS_ALPHAFLATBLEND | \
  469. D3DPSHADECAPS_ALPHAFLATSTIPPLED, \
  470. D3DPTEXTURECAPS_PERSPECTIVE | /* textureCaps */ \
  471. D3DPTEXTURECAPS_ALPHA | \
  472. D3DPTEXTURECAPS_POW2 | \
  473. D3DPTEXTURECAPS_TRANSPARENCY, \
  474. D3DPTFILTERCAPS_NEAREST | /* textureFilterCaps*/ \
  475. D3DPTFILTERCAPS_LINEAR, \
  476. D3DPTBLENDCAPS_DECAL | /* textureBlendCaps */ \
  477. D3DPTBLENDCAPS_DECALALPHA | \
  478. D3DPTBLENDCAPS_MODULATE | \
  479. D3DPTBLENDCAPS_MODULATEALPHA | \
  480. D3DPTBLENDCAPS_COPY, \
  481. D3DPTADDRESSCAPS_WRAP | /* textureAddressCaps */\
  482. D3DPTADDRESSCAPS_MIRROR | \
  483. D3DPTADDRESSCAPS_CLAMP | \
  484. D3DPTADDRESSCAPS_INDEPENDENTUV, \
  485. 8, /* stippleWidth */ \
  486. 8 /* stippleHeight */ \
  487. }
  488. static D3DDEVICEDESC_V1 PermediaCaps = {
  489. sizeof(D3DDEVICEDESC_V1), /* dwSize */
  490. D3DDD_COLORMODEL | /* dwFlags */
  491. D3DDD_DEVCAPS |
  492. D3DDD_TRICAPS |
  493. D3DDD_LINECAPS |
  494. D3DDD_DEVICERENDERBITDEPTH |
  495. D3DDD_DEVICEZBUFFERBITDEPTH,
  496. D3DCOLOR_RGB /*| D3DCOLOR_MONO*/, /* dcmColorModel */
  497. D3DDEVCAPS_FLOATTLVERTEX | /* devCaps */
  498. D3DDEVCAPS_DRAWPRIMITIVES2 |
  499. D3DDEVCAPS_DRAWPRIMITIVES2EX |
  500. #if D3DDX7_TL
  501. D3DDEVCAPS_HWTRANSFORMANDLIGHT |
  502. #endif //D3DDX7_TL
  503. D3DDEVCAPS_SORTINCREASINGZ |
  504. D3DDEVCAPS_SORTEXACT |
  505. D3DDEVCAPS_TLVERTEXSYSTEMMEMORY |
  506. D3DDEVCAPS_EXECUTESYSTEMMEMORY |
  507. D3DDEVCAPS_TEXTUREVIDEOMEMORY,
  508. { sizeof(D3DTRANSFORMCAPS),
  509. 0 }, /* transformCaps */
  510. FALSE, /* bClipping */
  511. { sizeof(D3DLIGHTINGCAPS),
  512. 0 }, /* lightingCaps */
  513. PermediaTriCaps, /* lineCaps */
  514. PermediaTriCaps, /* triCaps */
  515. DDBD_16 | DDBD_32, /* dwDeviceRenderBitDepth */
  516. DDBD_16, /* Z Bit depths */
  517. 0, /* dwMaxBufferSize */
  518. 0 /* dwMaxVertexCount */
  519. };
  520. // Alpha Stipple patterns from Foley And Van Dam
  521. DWORD FlatStipplePatterns[128] =
  522. {
  523. //Pattern 0
  524. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  525. // Pattern 1
  526. 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00,
  527. // Pattern 2
  528. 0xAA, 0x00, 0x22, 0x00, 0xAA, 0x00, 0x22, 0x00,
  529. // Pattern 3
  530. 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00,
  531. // Pattern 4
  532. 0xAA, 0x44, 0xAA, 0x00, 0xAA, 0x44, 0xAA, 0x00,
  533. // Pattern 5
  534. 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11,
  535. // Pattern 6
  536. 0xAA, 0x55, 0xAA, 0x11, 0xAA, 0x55, 0xAA, 0x11,
  537. // Pattern 7
  538. 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
  539. // Pattern 8
  540. 0xEE, 0x55, 0xAA, 0x55, 0xEE, 0x55, 0xAA, 0x55,
  541. // Pattern 9
  542. 0xEE, 0x55, 0xBB, 0x55, 0xEE, 0x55, 0xBB, 0x55,
  543. // Pattern 10
  544. 0xFF, 0x55, 0xBB, 0x55, 0xFF, 0x55, 0xBB, 0x55,
  545. // Pattern 11
  546. 0xFF, 0x55, 0xFF, 0x55, 0xFF, 0x55, 0xFF, 0x55,
  547. // Pattern 12
  548. 0xFF, 0xdd, 0xFF, 0x55, 0xFF, 0xdd, 0xFF, 0x55,
  549. // Pattern 13
  550. 0xFF, 0xdd, 0xFF, 0x77, 0xFF, 0xdd, 0xFF, 0x77,
  551. // Pattern 14
  552. 0xFF, 0xFF, 0xFF, 0x77, 0xFF, 0xFF, 0xFF, 0x77,
  553. // Pattern 15
  554. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  555. };
  556. //-----------------------------------------------------------------------------
  557. // gD3DTextureFormats is a static structure which contains information
  558. // pertaining to pixel format, dimensions, bit depth, surface requirements,
  559. // overlays, and FOURCC codes of the supported texture formats. These texture
  560. // formats will vary with the driver implementation according to the
  561. // capabilities of the hardware.
  562. //-----------------------------------------------------------------------------
  563. DDSURFACEDESC gD3DTextureFormats [] =
  564. {
  565. // 5:5:5 RGB format
  566. {
  567. sizeof(DDSURFACEDESC), // dwSize
  568. DDSD_CAPS | DDSD_PIXELFORMAT, // dwFlags
  569. 0, // dwHeight
  570. 0, // dwWidth
  571. 0, // lPitch
  572. 0, // dwBackBufferCount
  573. 0, // dwZBufferBitDepth
  574. 0, // dwAlphaBitDepth
  575. 0, // dwReserved
  576. NULL, // lpSurface
  577. { 0, 0 }, // ddckCKDestOverlay
  578. { 0, 0 }, // ddckCKDestBlt
  579. { 0, 0 }, // ddckCKSrcOverlay
  580. { 0, 0 }, // ddckCKSrcBlt
  581. {
  582. sizeof(DDPIXELFORMAT), // ddpfPixelFormat.dwSize
  583. DDPF_RGB, // ddpfPixelFormat.dwFlags
  584. 0, // ddpfPixelFormat.dwFourCC
  585. 16, // ddpfPixelFormat.dwRGBBitCount
  586. 0x7c00, // ddpfPixelFormat.dwRBitMask
  587. 0x03e0, // ddpfPixelFormat.dwGBitMask
  588. 0x001f, // ddpfPixelFormat.dwBBitMask
  589. 0 // ddpfPixelFormat.dwAlphaBitMask
  590. },
  591. DDSCAPS_TEXTURE, // ddscaps.dwCaps
  592. },
  593. // 1:5:5:5 ARGB format
  594. {
  595. sizeof(DDSURFACEDESC), // dwSize
  596. DDSD_CAPS | DDSD_PIXELFORMAT, // dwFlags
  597. 0, // dwHeight
  598. 0, // dwWidth
  599. 0, // lPitch
  600. 0, // dwBackBufferCount
  601. 0, // dwZBufferBitDepth
  602. 0, // dwAlphaBitDepth
  603. 0, // dwReserved
  604. NULL, // lpSurface
  605. { 0, 0 }, // ddckCKDestOverlay
  606. { 0, 0 }, // ddckCKDestBlt
  607. { 0, 0 }, // ddckCKSrcOverlay
  608. { 0, 0 }, // ddckCKSrcBlt
  609. {
  610. sizeof(DDPIXELFORMAT), // ddpfPixelFormat.dwSize
  611. DDPF_RGB | DDPF_ALPHAPIXELS, // ddpfPixelFormat.dwFlags
  612. 0, // ddpfPixelFormat.dwFourCC
  613. 16, // ddpfPixelFormat.dwRGBBitCount
  614. 0x7c00, // ddpfPixelFormat.dwRBitMask
  615. 0x03e0, // ddpfPixelFormat.dwGBitMask
  616. 0x001f, // ddpfPixelFormat.dwBBitMask
  617. 0x8000 // ddpfPixelFormat.dwAlphaBitMask
  618. },
  619. DDSCAPS_TEXTURE, // ddscaps.dwCaps
  620. },
  621. // 5:6:5 RGB format
  622. {
  623. sizeof(DDSURFACEDESC), // dwSize
  624. DDSD_CAPS | DDSD_PIXELFORMAT, // dwFlags
  625. 0, // dwHeight
  626. 0, // dwWidth
  627. 0, // lPitch
  628. 0, // dwBackBufferCount
  629. 0, // dwZBufferBitDepth
  630. 0, // dwAlphaBitDepth
  631. 0, // dwReserved
  632. NULL, // lpSurface
  633. { 0, 0 }, // ddckCKDestOverlay
  634. { 0, 0 }, // ddckCKDestBlt
  635. { 0, 0 }, // ddckCKSrcOverlay
  636. { 0, 0 }, // ddckCKSrcBlt
  637. {
  638. sizeof(DDPIXELFORMAT), // ddpfPixelFormat.dwSize
  639. DDPF_RGB, // ddpfPixelFormat.dwFlags
  640. 0, // ddpfPixelFormat.dwFourCC
  641. 16, // ddpfPixelFormat.dwRGBBitCount
  642. 0xf800, // ddpfPixelFormat.dwRBitMask
  643. 0x07e0, // ddpfPixelFormat.dwGBitMask
  644. 0x001f, // ddpfPixelFormat.dwBBitMask
  645. 0 // ddpfPixelFormat.dwAlphaBitMask
  646. },
  647. DDSCAPS_TEXTURE, // ddscaps.dwCaps
  648. },
  649. // 4:4:4:4 ARGB format
  650. {
  651. sizeof(DDSURFACEDESC), // dwSize
  652. DDSD_CAPS | DDSD_PIXELFORMAT, // dwFlags
  653. 0, // dwHeight
  654. 0, // dwWidth
  655. 0, // lPitch
  656. 0, // dwBackBufferCount
  657. 0, // dwZBufferBitDepth
  658. 0, // dwAlphaBitDepth
  659. 0, // dwReserved
  660. NULL, // lpSurface
  661. { 0, 0 }, // ddckCKDestOverlay
  662. { 0, 0 }, // ddckCKDestBlt
  663. { 0, 0 }, // ddckCKSrcOverlay
  664. { 0, 0 }, // ddckCKSrcBlt
  665. {
  666. sizeof(DDPIXELFORMAT), // ddpfPixelFormat.dwSize
  667. DDPF_RGB | DDPF_ALPHAPIXELS, // ddpfPixelFormat.dwFlags
  668. 0, // ddpfPixelFormat.dwFourCC
  669. 16, // ddpfPixelFormat.dwRGBBitCount
  670. 0x0f00, // ddpfPixelFormat.dwRBitMask
  671. 0x00f0, // ddpfPixelFormat.dwGBitMask
  672. 0x000f, // ddpfPixelFormat.dwBBitMask
  673. 0xf000 // ddpfPixelFormat.dwAlphaBitMask
  674. },
  675. DDSCAPS_TEXTURE, // ddscaps.dwCaps
  676. },
  677. // 8:8:8 RGB format
  678. {
  679. sizeof(DDSURFACEDESC), // dwSize
  680. DDSD_CAPS | DDSD_PIXELFORMAT, // dwFlags
  681. 0, // dwHeight
  682. 0, // dwWidth
  683. 0, // lPitch
  684. 0, // dwBackBufferCount
  685. 0, // dwZBufferBitDepth
  686. 0, // dwAlphaBitDepth
  687. 0, // dwReserved
  688. NULL, // lpSurface
  689. { 0, 0 }, // ddckCKDestOverlay
  690. { 0, 0 }, // ddckCKDestBlt
  691. { 0, 0 }, // ddckCKSrcOverlay
  692. { 0, 0 }, // ddckCKSrcBlt
  693. {
  694. sizeof(DDPIXELFORMAT), // ddpfPixelFormat.dwSize
  695. DDPF_RGB, // ddpfPixelFormat.dwFlags
  696. 0, // ddpfPixelFormat.dwFourCC
  697. 32, // ddpfPixelFormat.dwRGBBitCount
  698. 0x00ff0000, // ddpfPixelFormat.dwRBitMask
  699. 0x0000ff00, // ddpfPixelFormat.dwGBitMask
  700. 0x000000ff, // ddpfPixelFormat.dwBBitMask
  701. 0 // ddpfPixelFormat.dwAlphaBitMask
  702. },
  703. DDSCAPS_TEXTURE, // ddscaps.dwCaps
  704. },
  705. // 8:8:8:8 ARGB format
  706. {
  707. sizeof(DDSURFACEDESC), // dwSize
  708. DDSD_CAPS | DDSD_PIXELFORMAT, // dwFlags
  709. 0, // dwHeight
  710. 0, // dwWidth
  711. 0, // lPitch
  712. 0, // dwBackBufferCount
  713. 0, // dwZBufferBitDepth
  714. 0, // dwAlphaBitDepth
  715. 0, // dwReserved
  716. NULL, // lpSurface
  717. { 0, 0 }, // ddckCKDestOverlay
  718. { 0, 0 }, // ddckCKDestBlt
  719. { 0, 0 }, // ddckCKSrcOverlay
  720. { 0, 0 }, // ddckCKSrcBlt
  721. {
  722. sizeof(DDPIXELFORMAT), // ddpfPixelFormat.dwSize
  723. DDPF_RGB | DDPF_ALPHAPIXELS, // ddpfPixelFormat.dwFlags
  724. 0, // ddpfPixelFormat.dwFourCC
  725. 32, // ddpfPixelFormat.dwRGBBitCount
  726. 0x00ff0000, // ddpfPixelFormat.dwRBitMask
  727. 0x0000ff00, // ddpfPixelFormat.dwGBitMask
  728. 0x000000ff, // ddpfPixelFormat.dwBBitMask
  729. 0xff000000 // ddpfPixelFormat.dwAlphaBitMask
  730. },
  731. DDSCAPS_TEXTURE, // ddscaps.dwCaps
  732. },
  733. // 4 bit palettized format
  734. {
  735. sizeof(DDSURFACEDESC), // dwSize
  736. DDSD_CAPS | DDSD_PIXELFORMAT, // dwFlags
  737. 0, // dwHeight
  738. 0, // dwWidth
  739. 0, // lPitch
  740. 0, // dwBackBufferCount
  741. 0, // dwZBufferBitDepth
  742. 0, // dwAlphaBitDepth
  743. 0, // dwReserved
  744. NULL, // lpSurface
  745. { 0, 0 }, // ddckCKDestOverlay
  746. { 0, 0 }, // ddckCKDestBlt
  747. { 0, 0 }, // ddckCKSrcOverlay
  748. { 0, 0 }, // ddckCKSrcBlt
  749. {
  750. sizeof(DDPIXELFORMAT), // ddpfPixelFormat.dwSize
  751. DDPF_RGB | DDPF_PALETTEINDEXED4, // ddpfPixelFormat.dwFlags
  752. 0, // ddpfPixelFormat.dwFourCC
  753. 4, // ddpfPixelFormat.dwRGBBitCount
  754. 0x00, // ddpfPixelFormat.dwRBitMask
  755. 0x00, // ddpfPixelFormat.dwGBitMask
  756. 0x00, // ddpfPixelFormat.dwBBitMask
  757. 0x00 // ddpfPixelFormat.dwAlphaBitMask
  758. },
  759. DDSCAPS_TEXTURE, // ddscaps.dwCaps
  760. },
  761. // 8 bit palettized format
  762. {
  763. sizeof(DDSURFACEDESC), // dwSize
  764. DDSD_CAPS | DDSD_PIXELFORMAT, // dwFlags
  765. 0, // dwHeight
  766. 0, // dwWidth
  767. 0, // lPitch
  768. 0, // dwBackBufferCount
  769. 0, // dwZBufferBitDepth
  770. 0, // dwAlphaBitDepth
  771. 0, // dwReserved
  772. NULL, // lpSurface
  773. { 0, 0 }, // ddckCKDestOverlay
  774. { 0, 0 }, // ddckCKDestBlt
  775. { 0, 0 }, // ddckCKSrcOverlay
  776. { 0, 0 }, // ddckCKSrcBlt
  777. {
  778. sizeof(DDPIXELFORMAT), // ddpfPixelFormat.dwSize
  779. DDPF_RGB | DDPF_PALETTEINDEXED8, // ddpfPixelFormat.dwFlags
  780. 0, // ddpfPixelFormat.dwFourCC
  781. 8, // ddpfPixelFormat.dwRGBBitCount
  782. 0x00, // ddpfPixelFormat.dwRBitMask
  783. 0x00, // ddpfPixelFormat.dwGBitMask
  784. 0x00, // ddpfPixelFormat.dwBBitMask
  785. 0x00 // ddpfPixelFormat.dwAlphaBitMask
  786. },
  787. DDSCAPS_TEXTURE, // ddscaps.dwCaps
  788. },
  789. };
  790. ULONG gD3DNumberOfTextureFormats =
  791. sizeof(gD3DTextureFormats) / sizeof(DDSURFACEDESC);
  792. //------------------------------------------------------------------------------
  793. // D3D working structures for callbacks and global data
  794. //------------------------------------------------------------------------------
  795. // D3D callbacks and global data
  796. D3DHAL_GLOBALDRIVERDATA gD3DGlobalDriverData;
  797. D3DHAL_CALLBACKS gD3DCallBacks;
  798. // D3D contexts table
  799. // each entry points to a valid PERMEDIA_D3DCONTEXT structure
  800. UINT_PTR ContextSlots[MAX_CONTEXT_NUM] = {0};
  801. // Handles table
  802. // each entry is a DWLIST structure (*dwSurfaceList,*dwPaletteList;pDDLcl)
  803. DWLIST HandleList[MAX_CONTEXT_NUM] = {0};
  804. //-----------------------------------------------------------------------------
  805. //
  806. // void D3DHALCreateDriver
  807. //
  808. // The main D3D Callback.
  809. // Clears contexts
  810. // Fills in entry points to D3D driver.
  811. // Generates texture formats.
  812. //
  813. //-----------------------------------------------------------------------------
  814. void CALLBACK
  815. D3DHALCreateDriver(PPDev ppdev,
  816. LPD3DHAL_GLOBALDRIVERDATA* lpD3DGlobalDriverData,
  817. LPD3DHAL_CALLBACKS* lpD3DHALCallbacks,
  818. LPDDHAL_D3DBUFCALLBACKS* lpDDExeBufCallbacks)
  819. {
  820. D3DHAL_GLOBALDRIVERDATA deviceD3DGlobal;
  821. D3DHAL_CALLBACKS deviceD3DHALCallbacks;
  822. DBG_D3D((6,"Entering D3DHALCreateDriver"));
  823. // Contexts are cleared out. It is allright to use the D3DInitialised BOOL,
  824. // because it is global, and therefore forced into shared data segment by
  825. // the build.
  826. if (D3DInitialised == FALSE)
  827. {
  828. // Clear the contexts.
  829. memset(ContextSlots, 0, (sizeof(ContextSlots[0]) * MAX_CONTEXT_NUM) );
  830. memset(HandleList, 0, (sizeof(HandleList[0]) * MAX_CONTEXT_NUM) );
  831. D3DInitialised = TRUE;
  832. }
  833. // Here we fill in the supplied structures.
  834. // Can disable D3D HAL in registry if we are in the wrong mode
  835. if (ppdev->iBitmapFormat == BMF_8BPP )
  836. {
  837. *lpD3DGlobalDriverData = NULL;
  838. *lpD3DHALCallbacks = NULL;
  839. *lpDDExeBufCallbacks = NULL;
  840. DBG_D3D((0, "D3DHALCreateDriver: Disabled"));
  841. return;
  842. }
  843. // Set the pointers for D3D global data
  844. ppdev->pD3DDriverData32 = (UINT_PTR)&gD3DGlobalDriverData;
  845. ppdev->pD3DHALCallbacks32 = (UINT_PTR)&gD3DCallBacks;
  846. // Clear the global data
  847. memset(&deviceD3DGlobal, 0, sizeof(D3DHAL_GLOBALDRIVERDATA));
  848. deviceD3DGlobal.dwSize = sizeof(D3DHAL_GLOBALDRIVERDATA);
  849. // Clear the call-backs
  850. memset(&deviceD3DHALCallbacks, 0, sizeof(D3DHAL_CALLBACKS));
  851. deviceD3DHALCallbacks.dwSize = sizeof(D3DHAL_CALLBACKS);
  852. deviceD3DGlobal.dwNumVertices = 0; // We don't parse execute buffers
  853. deviceD3DGlobal.dwNumClipVertices = 0;
  854. #if D3D_MIPMAPPING
  855. // Add mipmapping cap bits to our texturing capabilities
  856. PermediaCaps.dpcTriCaps.dwTextureFilterCaps |=
  857. D3DPTFILTERCAPS_MIPNEAREST |
  858. D3DPTFILTERCAPS_MIPLINEAR |
  859. D3DPTFILTERCAPS_LINEARMIPNEAREST |
  860. D3DPTFILTERCAPS_LINEARMIPLINEAR;
  861. PermediaCaps.dpcTriCaps.dwRasterCaps |= D3DPRASTERCAPS_MIPMAPLODBIAS;
  862. #endif
  863. // Can do packed 24 bit on P2.
  864. PermediaCaps.dwDeviceRenderBitDepth |= DDBD_24;
  865. if (DD_P2AGPCAPABLE(ppdev))
  866. PermediaCaps.dwDevCaps |= D3DDEVCAPS_TEXTURENONLOCALVIDMEM;
  867. PermediaCaps.dwDevCaps |= D3DDEVCAPS_DRAWPRIMTLVERTEX;
  868. deviceD3DGlobal.hwCaps = PermediaCaps;
  869. deviceD3DGlobal.dwNumTextureFormats = gD3DNumberOfTextureFormats;
  870. deviceD3DGlobal.lpTextureFormats = &gD3DTextureFormats[0];
  871. // D3D Context callbacks
  872. //@@BEGIN_DDKSPLIT
  873. #if MULTITHREADED
  874. deviceD3DHALCallbacks.ContextCreate = MtD3DContextCreate;
  875. deviceD3DHALCallbacks.ContextDestroy = MtD3DContextDestroy;
  876. #else
  877. //@@END_DDKSPLIT
  878. deviceD3DHALCallbacks.ContextCreate = D3DContextCreate;
  879. deviceD3DHALCallbacks.ContextDestroy = D3DContextDestroy;
  880. //@@BEGIN_DDKSPLIT
  881. #endif MULTITHREADED
  882. //@@END_DDKSPLIT
  883. //
  884. // Return the HAL table.
  885. //
  886. memcpy(&gD3DGlobalDriverData, &deviceD3DGlobal, sizeof(D3DHAL_GLOBALDRIVERDATA));
  887. memcpy(&gD3DCallBacks, &deviceD3DHALCallbacks, sizeof(D3DHAL_CALLBACKS));
  888. *lpD3DGlobalDriverData = &gD3DGlobalDriverData;
  889. *lpD3DHALCallbacks = &gD3DCallBacks;
  890. *lpDDExeBufCallbacks = NULL;
  891. DBG_D3D((6,"Exiting D3DHALCreateDriver"));
  892. return;
  893. } // D3DHALCreateDriver
  894. //-----------------------------------------------------------------------------
  895. //
  896. // void CleanDirect3DContext
  897. //
  898. // After it has been decided that a context is indeed still active
  899. // and is being freed, this function walks along cleaning everything
  900. // up. Note it can be called either as a result of a D3DContextDestroy,
  901. // or as a result of the app exiting without freeing the context, or
  902. // as the result of an error whilst creating the context.
  903. //
  904. //-----------------------------------------------------------------------------
  905. void
  906. CleanDirect3DContext(PERMEDIA_D3DCONTEXT* pContext, ULONG_PTR dwhContext)
  907. {
  908. PERMEDIA_D3DTEXTURE* pTexture;
  909. DWORD dwSlotNum = 1;
  910. PPDev ppdev = pContext->ppdev;
  911. DBG_D3D((10,"Entering CleanDirect3DContext"));
  912. // free up Permedia register context id (resources)
  913. if (pContext->hPermediaContext)
  914. {
  915. P2FreeContext( ppdev, pContext->hPermediaContext);
  916. }
  917. // clean up texture manager stuff it is already allocated for this context
  918. if (pContext->pTextureManager)
  919. {
  920. pContext->pTextureManager = NULL;
  921. P2TMcount--;
  922. if (0 == P2TMcount)
  923. {
  924. if (0 != P2TextureManager.m_heap.m_data_p)
  925. {
  926. TextureCacheManagerEvictTextures(&P2TextureManager);
  927. ENGFREEMEM(P2TextureManager.m_heap.m_data_p);
  928. P2TextureManager.m_heap.m_data_p=NULL;
  929. }
  930. }
  931. }
  932. #if D3D_STATEBLOCKS
  933. // Free up any remaining state sets
  934. __DeleteAllStateSets(pContext);
  935. #endif //D3D_STATEBLOCKS
  936. // Finally, free up the rendering context structure itself
  937. ENGFREEMEM((PVOID)pContext->Hdr.pSelf);
  938. // Mark the context as now empty!
  939. ContextSlots[dwhContext] = 0;
  940. DBG_D3D((10,"Exiting CleanDirect3DContext, Context 0x%x deleted.",
  941. dwhContext));
  942. } // CleanDirect3DContext
  943. //-----------------------------------------------------------------------------
  944. //
  945. // HRESULT InitPermediaContext
  946. //
  947. // Given a valid context, this sets up the rest of the chip, and
  948. // enables the relevent units. There is a software copy of most things.
  949. //
  950. //-----------------------------------------------------------------------------
  951. HRESULT
  952. InitPermediaContext(PERMEDIA_D3DCONTEXT* pContext)
  953. {
  954. PPDev ppdev = pContext->ppdev;
  955. DBG_D3D((10,"Entering InitPermediaContext"));
  956. SET_CURRENT_D3D_CONTEXT(pContext->hPermediaContext);
  957. // Initially turn off all.units
  958. __PermediaDisableUnits(pContext);
  959. // Setup initial state of Permedia 2 registers for this D3D context
  960. SetupDefaultsPermediaContext(pContext);
  961. DBG_D3D((10,"Exiting InitPermediaContext"));
  962. // Setup the correct surface (render & depth buffer) characteristics
  963. return SetupPermediaRenderTarget(pContext);
  964. } // InitPermediaContext
  965. //-----------------------------------------------------------------------------
  966. //
  967. // BOOL: SetupDefaultsPermediaContext
  968. //
  969. // Sets up the Permedia HW context(chip.registers) according to some D3D and
  970. // some HW specific defaults. Done only when initializing the context
  971. //
  972. //-----------------------------------------------------------------------------
  973. BOOL
  974. SetupDefaultsPermediaContext(PERMEDIA_D3DCONTEXT* pContext)
  975. {
  976. __P2RegsSoftwareCopy* pSoftPermedia = &pContext->Hdr.SoftCopyP2Regs;
  977. PERMEDIA_DEFS(pContext->ppdev);
  978. DBG_D3D((10,"Entering SetupDefaultsPermediaContext"));
  979. //=========================================================================
  980. // Initialize our software copy of some registers for their default values
  981. //=========================================================================
  982. // Setup the default & constant ( Z Buffer) LB settings
  983. // this will be updated into the chip in SetupPermediaRenderTarget
  984. pSoftPermedia->LBReadMode.WindowOrigin = __PERMEDIA_TOP_LEFT_WINDOW_ORIGIN;
  985. pSoftPermedia->LBReadMode.DataType = __PERMEDIA_LBDEFAULT; // default
  986. pSoftPermedia->LBReadMode.ReadSourceEnable = __PERMEDIA_DISABLE;
  987. pSoftPermedia->LBReadMode.ReadDestinationEnable = __PERMEDIA_DISABLE;
  988. pSoftPermedia->LBReadMode.PatchMode = 0;
  989. // Setup the default & constant FB settings
  990. // this will be updated into the chip in SetupPermediaRenderTarget
  991. pSoftPermedia->FBReadMode.ReadSourceEnable = __PERMEDIA_DISABLE;
  992. pSoftPermedia->FBReadMode.ReadDestinationEnable = __PERMEDIA_DISABLE;
  993. pSoftPermedia->FBReadMode.DataType = __PERMEDIA_FBDATA;
  994. // Top Left for D3D origin
  995. pSoftPermedia->FBReadMode.WindowOrigin = __PERMEDIA_TOP_LEFT_WINDOW_ORIGIN;
  996. pSoftPermedia->FBReadMode.PatchMode = 0;
  997. pSoftPermedia->FBReadMode.PackedData = 0;
  998. pSoftPermedia->FBReadMode.RelativeOffset = 0;
  999. // Setup the default & constant Alpha Blend Mode settings
  1000. // this will be updated into the chip in SetupPermediaRenderTarget
  1001. pSoftPermedia->AlphaBlendMode.AlphaBlendEnable = 0;
  1002. pSoftPermedia->AlphaBlendMode.SourceBlend = __PERMEDIA_BLEND_FUNC_ONE;
  1003. pSoftPermedia->AlphaBlendMode.DestinationBlend = __PERMEDIA_BLEND_FUNC_ZERO;
  1004. pSoftPermedia->AlphaBlendMode.NoAlphaBuffer = 0;
  1005. pSoftPermedia->AlphaBlendMode.ColorOrder = COLOR_MODE;
  1006. pSoftPermedia->AlphaBlendMode.BlendType = 0;
  1007. pSoftPermedia->AlphaBlendMode.ColorConversion = 1;
  1008. pSoftPermedia->AlphaBlendMode.AlphaConversion = 1;
  1009. // Setup the default & constant Dither Mode settings
  1010. // this will be updated into the chip in SetupPermediaRenderTarget
  1011. pSoftPermedia->DitherMode.ColorOrder = COLOR_MODE;
  1012. pSoftPermedia->DitherMode.XOffset = DITHER_XOFFSET;
  1013. pSoftPermedia->DitherMode.YOffset = DITHER_YOFFSET;
  1014. pSoftPermedia->DitherMode.UnitEnable = __PERMEDIA_ENABLE;
  1015. pSoftPermedia->DitherMode.ForceAlpha = 0;
  1016. //=========================================================================
  1017. // Find out info for memory widths
  1018. //=========================================================================
  1019. PPDev ppdev = pContext->ppdev;
  1020. DBG_D3D((4, "ScreenWidth %d, ScreenHeight %d, Bytes/Pixel %d",
  1021. ppdev->cxScreen, ppdev->cyScreen,
  1022. ppdev->ddpfDisplay.dwRGBBitCount >> 3));
  1023. vCalcPackedPP( ppdev->cxMemory, NULL, &pContext->ulPackedPP);
  1024. DBG_D3D((4, "PackedPP = %04x", pContext->ulPackedPP));
  1025. //=========================================================================
  1026. // Initialize hardware registers to their default values
  1027. //=========================================================================
  1028. // Number of registers we are going to set up
  1029. RESERVEDMAPTR(34);
  1030. // ----------------- Render and Depth Buffer setup ----------------------
  1031. // Setup default offset of render buffer in video memory
  1032. SEND_PERMEDIA_DATA(FBWindowBase, 0x0);
  1033. // Setup offset from destination to source for copy operations
  1034. SEND_PERMEDIA_DATA(FBSourceOffset, 0x0);
  1035. // Render buffer Write Mode setup
  1036. pSoftPermedia->FBWriteMode.UnitEnable = __PERMEDIA_ENABLE;
  1037. COPY_PERMEDIA_DATA(FBWriteMode, pSoftPermedia->FBWriteMode);
  1038. // Render buffer Write Masks (write to all bits in the pixel)
  1039. SEND_PERMEDIA_DATA(FBSoftwareWriteMask, __PERMEDIA_ALL_WRITEMASKS_SET);
  1040. SEND_PERMEDIA_DATA(FBHardwareWriteMask, __PERMEDIA_ALL_WRITEMASKS_SET);
  1041. // Set block fill colour to black
  1042. SEND_PERMEDIA_DATA(FBBlockColor, 0x0);
  1043. // Set window origin offsets to (0,0)
  1044. SEND_PERMEDIA_DATA(WindowOrigin, 0x0);
  1045. // WindowSetup
  1046. pSoftPermedia->Window.ForceLBUpdate = 0;
  1047. pSoftPermedia->Window.LBUpdateSource = 0;
  1048. pSoftPermedia->Window.DisableLBUpdate = 0;
  1049. COPY_PERMEDIA_DATA(Window, pSoftPermedia->Window);
  1050. // Disable Screen Scissor unit
  1051. SEND_PERMEDIA_DATA(ScissorMode, __PERMEDIA_DISABLE);
  1052. // Depth Buffer offset
  1053. SEND_PERMEDIA_DATA(LBSourceOffset, 0);
  1054. // Depth Buffer Write mode (initially allow LB Writes)
  1055. pSoftPermedia->LBWriteMode.WriteEnable = __PERMEDIA_DISABLE;
  1056. COPY_PERMEDIA_DATA(LBWriteMode, pSoftPermedia->LBWriteMode);
  1057. // Depth comparisons
  1058. pSoftPermedia->DepthMode.WriteMask = __PERMEDIA_ENABLE;
  1059. pSoftPermedia->DepthMode.CompareMode =
  1060. __PERMEDIA_DEPTH_COMPARE_MODE_LESS_OR_EQUAL;
  1061. pSoftPermedia->DepthMode.NewDepthSource = __PERMEDIA_DEPTH_SOURCE_DDA;
  1062. pSoftPermedia->DepthMode.UnitEnable = __PERMEDIA_DISABLE;
  1063. COPY_PERMEDIA_DATA(DepthMode, pSoftPermedia->DepthMode);
  1064. // ----------------- Texture units setup -----------------------------
  1065. // Enable texture address unit, disable perspective correction
  1066. pSoftPermedia->TextureAddressMode.Enable = 1;
  1067. pSoftPermedia->TextureAddressMode.PerspectiveCorrection = 0;
  1068. pSoftPermedia->TextureAddressMode.DeltaFormat = 0;
  1069. COPY_PERMEDIA_DATA(TextureAddressMode, pSoftPermedia->TextureAddressMode);
  1070. // Enable texture color mode unit, set modulation blending, no specular
  1071. // as defaults
  1072. pSoftPermedia->TextureColorMode.TextureEnable = 1;
  1073. pSoftPermedia->TextureColorMode.ApplicationMode = _P2_TEXTURE_MODULATE;
  1074. pSoftPermedia->TextureColorMode.TextureType = 0;
  1075. pSoftPermedia->TextureColorMode.KdDDA = 0;
  1076. pSoftPermedia->TextureColorMode.KsDDA = 0;
  1077. COPY_PERMEDIA_DATA(TextureColorMode, pSoftPermedia->TextureColorMode);
  1078. // Enable texture mapping unit, set frame buffer size as default texture
  1079. // map size (to be oevrriden in EnableTexturePermedia)
  1080. pSoftPermedia->TextureMapFormat.PackedPP = pContext->ulPackedPP;
  1081. pSoftPermedia->TextureMapFormat.WindowOrigin =
  1082. __PERMEDIA_TOP_LEFT_WINDOW_ORIGIN; //top left
  1083. pSoftPermedia->TextureMapFormat.SubPatchMode = 0;
  1084. pSoftPermedia->TextureMapFormat.TexelSize = 1;
  1085. COPY_PERMEDIA_DATA(TextureMapFormat, pSoftPermedia->TextureMapFormat);
  1086. // Setup Textura data format (to be oevrriden in EnableTexturePermedia)
  1087. pSoftPermedia->TextureDataFormat.TextureFormat = 1;
  1088. pSoftPermedia->TextureDataFormat.NoAlphaBuffer = 1;
  1089. pSoftPermedia->TextureDataFormat.ColorOrder = COLOR_MODE;
  1090. COPY_PERMEDIA_DATA(TextureDataFormat, pSoftPermedia->TextureDataFormat);
  1091. // Setup default texture map base address (in video memory)
  1092. SEND_PERMEDIA_DATA(TextureBaseAddress, 0);
  1093. // Setup texture reading defaults: Repeat s,t wrapping, 256x256 texture
  1094. // no texture filtering set up.
  1095. pSoftPermedia->TextureReadMode.PackedData = 0;
  1096. pSoftPermedia->TextureReadMode.FilterMode = 0;
  1097. pSoftPermedia->TextureReadMode.Height = 8;
  1098. pSoftPermedia->TextureReadMode.Width = 8;
  1099. pSoftPermedia->TextureReadMode.pad1 = 0;
  1100. pSoftPermedia->TextureReadMode.pad2 = 0;
  1101. pSoftPermedia->TextureReadMode.TWrapMode = _P2_TEXTURE_REPEAT;
  1102. pSoftPermedia->TextureReadMode.SWrapMode = _P2_TEXTURE_REPEAT;
  1103. pSoftPermedia->TextureReadMode.Enable = 1;
  1104. COPY_PERMEDIA_DATA(TextureReadMode, pSoftPermedia->TextureReadMode);
  1105. // Disable Texture LUT unit for palettized textures
  1106. SEND_PERMEDIA_DATA(TexelLUTMode, __PERMEDIA_DISABLE);
  1107. // -------------- Other rendering units setup ----------------
  1108. // Setup defaults of YUV units used for chromakey testing
  1109. pSoftPermedia->YUVMode.Enable = __PERMEDIA_DISABLE;
  1110. pSoftPermedia->YUVMode.TestMode = PM_YUVMODE_CHROMATEST_DISABLE;
  1111. pSoftPermedia->YUVMode.TestData = PM_YUVMODE_TESTDATA_INPUT;
  1112. pSoftPermedia->YUVMode.RejectTexel = FALSE;
  1113. pSoftPermedia->YUVMode.TexelDisableUpdate = FALSE;
  1114. COPY_PERMEDIA_DATA(YUVMode, pSoftPermedia->YUVMode);
  1115. // Chromakey values initially black
  1116. SEND_PERMEDIA_DATA(ChromaUpperBound, 0x00000000);
  1117. SEND_PERMEDIA_DATA(ChromaLowerBound, 0x00000000);
  1118. SEND_PERMEDIA_DATA(AlphaMapUpperBound, 0xFFFFFFFF);
  1119. SEND_PERMEDIA_DATA(AlphaMapLowerBound, 0x11000000);
  1120. // Default Fog color is white
  1121. pSoftPermedia->FogColor = 0xFFFFFFFF;
  1122. SEND_PERMEDIA_DATA(FogColor, pSoftPermedia->FogColor);
  1123. // Fog setup
  1124. pSoftPermedia->FogMode.FogEnable = 1;
  1125. COPY_PERMEDIA_DATA(FogMode, pSoftPermedia->FogMode);
  1126. // Stencil mode setup
  1127. pSoftPermedia->StencilMode.DPFail = __PERMEDIA_STENCIL_METHOD_KEEP;
  1128. pSoftPermedia->StencilMode.DPPass = __PERMEDIA_STENCIL_METHOD_KEEP;
  1129. pSoftPermedia->StencilMode.UnitEnable = __PERMEDIA_DISABLE;
  1130. pSoftPermedia->StencilMode.StencilSource =
  1131. __PERMEDIA_STENCIL_SOURCE_TEST_LOGIC;
  1132. COPY_PERMEDIA_DATA(StencilMode, pSoftPermedia->StencilMode);
  1133. // Host out unit , disable read backs
  1134. SEND_PERMEDIA_DATA(FilterMode, __PERMEDIA_DISABLE);
  1135. // Disable statistics unit
  1136. SEND_PERMEDIA_DATA(StatisticMode, __PERMEDIA_DISABLE);
  1137. // ----------------- Rasterization setup -----------------------------
  1138. // Setup Rasterizer units defaults
  1139. SEND_PERMEDIA_DATA(RasterizerMode, 0);
  1140. // Setup a step of -1, as this doesn't change very much
  1141. SEND_PERMEDIA_DATA(dY, 0xFFFF0000);
  1142. // Setup for Gourand shaded colour model, and enable unit
  1143. pContext->Hdr.SoftCopyP2Regs.ColorDDAMode.UnitEnable = 1;
  1144. pContext->Hdr.SoftCopyP2Regs.ColorDDAMode.ShadeMode = 1;
  1145. COPY_PERMEDIA_DATA(ColorDDAMode, pContext->Hdr.SoftCopyP2Regs.ColorDDAMode);
  1146. // Disable stippling unit
  1147. SEND_PERMEDIA_DATA(AreaStippleMode, 0x0); //AZN
  1148. // Setup the Delta setup chip for rasterization
  1149. pSoftPermedia->DeltaMode.TargetChip = 2;
  1150. pSoftPermedia->DeltaMode.SpecularTextureEnable = 0;
  1151. // The below changes to normalize in the perspective case
  1152. // It must not be on in the non-perspective case as the bad Q's will
  1153. // get used in the normalisation.
  1154. pSoftPermedia->DeltaMode.TextureParameterMode = 1;
  1155. pSoftPermedia->DeltaMode.TextureEnable = 1;
  1156. pSoftPermedia->DeltaMode.DiffuseTextureEnable = 0;
  1157. pSoftPermedia->DeltaMode.FogEnable = 1;
  1158. pSoftPermedia->DeltaMode.SmoothShadingEnable = 1;
  1159. pSoftPermedia->DeltaMode.DepthEnable = 0;
  1160. pSoftPermedia->DeltaMode.SubPixelCorrectionEnable = 1;
  1161. pSoftPermedia->DeltaMode.DiamondExit = 1;
  1162. pSoftPermedia->DeltaMode.NoDraw = 0;
  1163. pSoftPermedia->DeltaMode.ClampEnable = 0;
  1164. pSoftPermedia->DeltaMode.FillDirection = 0;
  1165. #ifndef P2_CHIP_CULLING
  1166. pSoftPermedia->DeltaMode.BackfaceCull = 0;
  1167. #else
  1168. pSoftPermedia->DeltaMode.BackfaceCull = 1;
  1169. #endif
  1170. pSoftPermedia->DeltaMode.ColorOrder = COLOR_MODE;
  1171. COPY_PERMEDIA_DATA(DeltaMode, pSoftPermedia->DeltaMode);
  1172. // Send all this data to Permedia2
  1173. COMMITDMAPTR();
  1174. FLUSHDMA();
  1175. DBG_D3D((10,"Exiting SetupDefaultsPermediaContext"));
  1176. return TRUE;
  1177. } // SetupDefaultsPermediaContext
  1178. //-----------------------------------------------------------------------------
  1179. //
  1180. // void SetupPermediaRenderTarget
  1181. //
  1182. // Sets up the correct surface characteristics (format, stride, etc) of the
  1183. // render buffer and the depth buffer in the Permedia registers
  1184. //
  1185. //-----------------------------------------------------------------------------
  1186. HRESULT
  1187. SetupPermediaRenderTarget(PERMEDIA_D3DCONTEXT* pContext)
  1188. {
  1189. __P2RegsSoftwareCopy* pSoftPermedia = &pContext->Hdr.SoftCopyP2Regs;
  1190. PPDev ppdev = pContext->ppdev;
  1191. PPERMEDIA_D3DTEXTURE pSurfRender,pSurfZBuffer;
  1192. PermediaSurfaceData* pPrivateRender;
  1193. PERMEDIA_DEFS(pContext->ppdev);
  1194. DBG_D3D((10,"Entering SetupPermediaRenderTarget"));
  1195. pSurfRender =
  1196. TextureHandleToPtr(pContext->RenderSurfaceHandle, pContext);
  1197. if (!CHECK_D3DSURFACE_VALIDITY(pSurfRender))
  1198. {
  1199. DBG_D3D((0,"ERROR: SetupPermediaRenderTarget"
  1200. " Invalid pSurfRender handle=%08lx",
  1201. pContext->RenderSurfaceHandle));
  1202. return DDERR_INVALIDPARAMS;
  1203. }
  1204. if (DDSCAPS_SYSTEMMEMORY & pSurfRender->dwCaps)
  1205. {
  1206. DBG_D3D((0, "ERROR: SetupPermediaRenderTarget"
  1207. " Render Surface in SYSTEMMEMORY handle=%08lx",
  1208. pContext->RenderSurfaceHandle));
  1209. return DDERR_INVALIDPARAMS;
  1210. }
  1211. pPrivateRender=pSurfRender->pTextureSurface;
  1212. if (!CHECK_P2_SURFACEDATA_VALIDITY(pPrivateRender))
  1213. {
  1214. DBG_D3D((0,"ERROR: SetupPermediaRenderTarget"
  1215. " invalid pSurfRender->pTextureSurface handle=%08lx",
  1216. pContext->RenderSurfaceHandle));
  1217. return DDERR_INVALIDPARAMS;
  1218. }
  1219. if (0 != pContext->ZBufferHandle)
  1220. {
  1221. pSurfZBuffer =
  1222. TextureHandleToPtr(pContext->ZBufferHandle, pContext);
  1223. if (!CHECK_D3DSURFACE_VALIDITY(pSurfZBuffer))
  1224. {
  1225. DBG_D3D((0,"ERROR: SetupPermediaRenderTarget"
  1226. " invalid pSurfZBuffer handle=%08lx",
  1227. pContext->ZBufferHandle));
  1228. pContext->ZBufferHandle = 0;
  1229. }
  1230. else
  1231. if (DDSCAPS_SYSTEMMEMORY & pSurfZBuffer->dwCaps)
  1232. {
  1233. DBG_D3D((0, "ERROR: SetupPermediaRenderTarget"
  1234. " pSurfZBuffer in SYSTEMMEMORY handle=%08lx",
  1235. pContext->ZBufferHandle));
  1236. pContext->ZBufferHandle = 0;
  1237. }
  1238. else
  1239. if (!CHECK_P2_SURFACEDATA_VALIDITY(pSurfZBuffer->pTextureSurface))
  1240. {
  1241. DBG_D3D((0,"ERROR: SetupPermediaRenderTarget"
  1242. " invalid pSurfZBuffer->pTextureSurface handle=%08lx",
  1243. pContext->ZBufferHandle));
  1244. pContext->ZBufferHandle = 0;
  1245. }
  1246. }
  1247. // The default is linear surfaces...
  1248. DBG_D3D((4,"Rendered surface Width: %d", pSurfRender->wWidth));
  1249. pSoftPermedia->FBReadMode.PackedPP = pSurfRender->pTextureSurface->ulPackedPP;
  1250. pContext->PixelOffset =
  1251. (DWORD)((UINT_PTR)pSurfRender->fpVidMem>>(pSurfRender->dwRGBBitCount>>4));
  1252. DBG_D3D((4,"Setting FBReadMode: 0x%x",pSoftPermedia->FBReadMode));
  1253. // Record the surface information
  1254. RESERVEDMAPTR(10);
  1255. // If there is a Z Buffer, then we must setup the Partial products to be
  1256. // the same as those chosen when it was allocated.
  1257. if (0 != pContext->ZBufferHandle)
  1258. {
  1259. PermediaSurfaceData* pPrivateZ = pSurfZBuffer->pTextureSurface;
  1260. pSoftPermedia->LBReadMode.PackedPP = pPrivateZ->ulPackedPP;
  1261. //actually check dwStencilBitMask
  1262. if (0==pPrivateZ->SurfaceFormat.BlueMask)
  1263. {
  1264. pSoftPermedia->LBReadFormat.DepthWidth = 0; // 16 bits
  1265. pSoftPermedia->LBReadFormat.StencilWidth = 0; // No Stencil
  1266. pSoftPermedia->DeltaMode.DepthFormat = 1; //PM_DELTAMODE_DEPTHWIDTH_16
  1267. }
  1268. else
  1269. {
  1270. pSoftPermedia->LBReadFormat.DepthWidth = 3; // 15 bits
  1271. pSoftPermedia->LBReadFormat.StencilWidth = 3; // 1 Stencil
  1272. pSoftPermedia->DeltaMode.DepthFormat = 0; //PM_DELTAMODE_DEPTHWIDTH_15
  1273. }
  1274. SEND_PERMEDIA_DATA(LBWindowBase,
  1275. (DWORD)((UINT_PTR)pSurfZBuffer->fpVidMem>>P2DEPTH16));
  1276. COPY_PERMEDIA_DATA(LBReadFormat, pSoftPermedia->LBReadFormat);
  1277. COPY_PERMEDIA_DATA(LBWriteFormat, pSoftPermedia->LBReadFormat);
  1278. DBG_D3D((4,"Setting LBReadMode: 0x%x",pSoftPermedia->LBReadMode));
  1279. }
  1280. else
  1281. { // No Z Buffer, just stuff the same Partial products as the desktop.
  1282. pSoftPermedia->LBReadMode.PackedPP = pContext->ulPackedPP;
  1283. }
  1284. COPY_PERMEDIA_DATA(FBReadMode, pSoftPermedia->FBReadMode);
  1285. COPY_PERMEDIA_DATA(LBReadMode, pSoftPermedia->LBReadMode);
  1286. // Set up the screen dimensions to be the same size as the surface.
  1287. SEND_PERMEDIA_DATA(ScreenSize,
  1288. (pSurfRender->wWidth & 0xFFFF) | (pSurfRender->wHeight << 16));
  1289. // DitherMode and AlphaBlendMode both depend on the surface pixel format
  1290. // being correct.
  1291. pSoftPermedia->DitherMode.ColorFormat =
  1292. pSoftPermedia->AlphaBlendMode.ColorFormat=
  1293. pPrivateRender->SurfaceFormat.Format;
  1294. pSoftPermedia->DitherMode.ColorFormatExtension =
  1295. pSoftPermedia->AlphaBlendMode.ColorFormatExtension =
  1296. pPrivateRender->SurfaceFormat.FormatExtension;
  1297. pSoftPermedia->FBReadPixel = pPrivateRender->SurfaceFormat.FBReadPixel;
  1298. SEND_PERMEDIA_DATA(FBReadPixel, pSoftPermedia->FBReadPixel);
  1299. SEND_PERMEDIA_DATA(FBPixelOffset, pContext->PixelOffset);
  1300. COPY_PERMEDIA_DATA(AlphaBlendMode, pSoftPermedia->AlphaBlendMode);
  1301. COPY_PERMEDIA_DATA(DitherMode, pSoftPermedia->DitherMode);
  1302. COMMITDMAPTR();
  1303. DBG_D3D((10,"Exiting SetupPermediaRenderTarget"));
  1304. return DD_OK;
  1305. } // SetupPermediaRenderTarget
  1306. //=============================================================================
  1307. //
  1308. // In the new DX7 DDI we don't have the Texture Create/Destroy/Swap calls
  1309. // anymore, so now we need a mechanism for generating texture handles. This
  1310. // is done by the runtime, which will associate a surface handle for each
  1311. // surface created with the DD local object, and will get our D3DCreateSurfaceEx
  1312. // callback called.
  1313. //
  1314. // Since this creation can very well happen before we create a D3D context, we
  1315. // need to keep track of this association, and when we do get called to create
  1316. // a D3D context, we will now be given the relevant DD local object pointer to
  1317. // resolve which handles are ours (and to which private texture structures we
  1318. // need to use).
  1319. //
  1320. // This mechanism is also used to associate a palette to a texture
  1321. //
  1322. //=============================================================================
  1323. //-----------------------------------------------------------------------------
  1324. //
  1325. // BOOL SetTextureSlot
  1326. //
  1327. // In the handle list element corresponding to this local DD object, store or
  1328. // update the pointer to the pTexture associated to the surface handle
  1329. // from the lpDDSLcl surface.
  1330. //
  1331. //-----------------------------------------------------------------------------
  1332. BOOL
  1333. SetTextureSlot(LPVOID pDDLcl,
  1334. LPDDRAWI_DDRAWSURFACE_LCL lpDDSLcl,
  1335. PPERMEDIA_D3DTEXTURE pTexture)
  1336. {
  1337. int i,j= -1;
  1338. DWORD dwSurfaceHandle;
  1339. DBG_D3D((10,"Entering SetTextureSlot"));
  1340. ASSERTDD(NULL != pDDLcl && NULL != lpDDSLcl && NULL != pTexture,
  1341. "SetTextureSlot invalid input");
  1342. dwSurfaceHandle = lpDDSLcl->lpSurfMore->dwSurfaceHandle;
  1343. // Find the handle list element associated with the local DD object,
  1344. // if there's none then select an empty one to be used
  1345. for (i = 0; i < MAX_CONTEXT_NUM;i++)
  1346. {
  1347. if (pDDLcl == HandleList[i].pDDLcl)
  1348. {
  1349. break; // found the right slot
  1350. }
  1351. else
  1352. if (0 == HandleList[i].pDDLcl && -1 == j)
  1353. {
  1354. j=i; // first empty slot !
  1355. }
  1356. }
  1357. // If we overrun the existing handle list elements, we need to
  1358. // initialize an existing empty slot or return an error.
  1359. if (i >= MAX_CONTEXT_NUM)
  1360. {
  1361. if (-1 != j)
  1362. {
  1363. //has an empty slot for this process, so use it
  1364. i = j;
  1365. HandleList[j].pDDLcl = pDDLcl;
  1366. ASSERTDD(NULL == HandleList[j].dwSurfaceList,"in SetTextureSlot");
  1367. }
  1368. else
  1369. {
  1370. //all process slots has been used, fail
  1371. DBG_D3D((0,"SetTextureSlot failed with pDDLcl=%x "
  1372. "dwSurfaceHandle=%08lx pTexture=%x",
  1373. pDDLcl,dwSurfaceHandle,pTexture));
  1374. return false;
  1375. }
  1376. }
  1377. ASSERTDD(i < MAX_CONTEXT_NUM, "in SetTextureSlot");
  1378. if ( NULL == HandleList[i].dwSurfaceList ||
  1379. dwSurfaceHandle >= PtrToUlong(HandleList[i].dwSurfaceList[0]))
  1380. {
  1381. // dwSurfaceHandle numbers are going to be ordinal numbers starting
  1382. // at one, so we use this number to figure out a "good" size for
  1383. // our new list.
  1384. DWORD newsize = ((dwSurfaceHandle + LISTGROWSIZE) / LISTGROWSIZE)
  1385. * LISTGROWSIZE;
  1386. PPERMEDIA_D3DTEXTURE *newlist= (PPERMEDIA_D3DTEXTURE *)
  1387. ENGALLOCMEM( FL_ZERO_MEMORY,
  1388. sizeof(PPERMEDIA_D3DTEXTURE)*newsize,
  1389. ALLOC_TAG);
  1390. DBG_D3D((4,"Growing pDDLcl=%x's SurfaceList[%x] size to %08lx",
  1391. pDDLcl,newlist,newsize));
  1392. if (NULL == newlist)
  1393. {
  1394. DBG_D3D((0,"SetTextureSlot failed to increase "
  1395. "HandleList[%d].dwSurfaceList",i));
  1396. return false;
  1397. }
  1398. memset(newlist,0,newsize);
  1399. // we had a formerly valid surfacehandle list, so we now must
  1400. // copy it over and free the memory allocated for it
  1401. if (NULL != HandleList[i].dwSurfaceList)
  1402. {
  1403. memcpy(newlist,HandleList[i].dwSurfaceList,
  1404. PtrToUlong(HandleList[i].dwSurfaceList[0]) *
  1405. sizeof(PPERMEDIA_D3DTEXTURE));
  1406. ENGFREEMEM(HandleList[i].dwSurfaceList);
  1407. DBG_D3D((4,"Freeing pDDLcl=%x's old SurfaceList[%x]",
  1408. pDDLcl,HandleList[i].dwSurfaceList));
  1409. }
  1410. HandleList[i].dwSurfaceList = newlist;
  1411. //store size in dwSurfaceList[0]
  1412. *(DWORD*)HandleList[i].dwSurfaceList = newsize;
  1413. }
  1414. // Store a pointer to the pTexture associated to this surface handle
  1415. HandleList[i].dwSurfaceList[dwSurfaceHandle] = pTexture;
  1416. pTexture->HandleListIndex = i; //store index here to facilitate search
  1417. DBG_D3D((4,"Set pDDLcl=%x Handle=%08lx pTexture = %x",
  1418. pDDLcl, dwSurfaceHandle, pTexture));
  1419. DBG_D3D((10,"Exiting SetTextureSlot"));
  1420. return true;
  1421. } // SetTextureSlot
  1422. //-----------------------------------------------------------------------------
  1423. //
  1424. // PPERMEDIA_D3DTEXTURE GetTextureSlot
  1425. //
  1426. // Find the pointer to the PPERMEDIA_D3DTEXTURE associated to the
  1427. // dwSurfaceHandle corresponding to the given local DD object
  1428. //
  1429. //-----------------------------------------------------------------------------
  1430. PPERMEDIA_D3DTEXTURE
  1431. GetTextureSlot(LPVOID pDDLcl, DWORD dwSurfaceHandle)
  1432. {
  1433. DBG_D3D((10,"Entering GetTextureSlot"));
  1434. DWORD i;
  1435. for (i = 0; i < MAX_CONTEXT_NUM; i++)
  1436. {
  1437. if (HandleList[i].pDDLcl == pDDLcl)
  1438. {
  1439. if (HandleList[i].dwSurfaceList &&
  1440. PtrToUlong(HandleList[i].dwSurfaceList[0]) > dwSurfaceHandle )
  1441. {
  1442. return HandleList[i].dwSurfaceList[dwSurfaceHandle];
  1443. }
  1444. else
  1445. break;
  1446. }
  1447. }
  1448. DBG_D3D((10,"Exiting GetTextureSlot"));
  1449. return NULL; //Not found
  1450. } // GetTextureSlot
  1451. //-----------------------------------------------------------------------------
  1452. //
  1453. // LPDWLIST GetSurfaceHandleList
  1454. //
  1455. // Get the handle list which is associated to a specific PDD_DIRECTDRAW_LOCAL
  1456. // pDDLcl. It is called from D3DContextCreate to get the handle list associated
  1457. // to the pDDLcl with which the context is being created.
  1458. //
  1459. //-----------------------------------------------------------------------------
  1460. LPDWLIST
  1461. GetSurfaceHandleList(LPVOID pDDLcl)
  1462. {
  1463. DWORD i;
  1464. DBG_D3D((10,"Entering GetSurfaceHandleList"));
  1465. ASSERTDD(NULL != pDDLcl, "GetSurfaceHandleList get NULL==pDDLcl");
  1466. for (i = 0; i < MAX_CONTEXT_NUM;i++)
  1467. {
  1468. if (HandleList[i].pDDLcl == pDDLcl)
  1469. {
  1470. DBG_D3D((4,"Getting pHandleList=%08lx for pDDLcl %x",
  1471. &HandleList[i],pDDLcl));
  1472. return &HandleList[i];
  1473. }
  1474. }
  1475. DBG_D3D((10,"Exiting GetSurfaceHandleList"));
  1476. return NULL; //No surface handle available yet
  1477. } // GetSurfaceHandleList
  1478. //-----------------------------------------------------------------------------
  1479. //
  1480. // void ReleaseSurfaceHandleList
  1481. //
  1482. // Free all the associated surface handle and palette memory pools associated
  1483. // to a given DD local object.
  1484. //
  1485. //-----------------------------------------------------------------------------
  1486. void
  1487. ReleaseSurfaceHandleList(LPVOID pDDLcl)
  1488. {
  1489. DWORD i;
  1490. DBG_D3D((10,"Entering ReleaseSurfaceHandleList"));
  1491. ASSERTDD(NULL != pDDLcl, "ReleaseSurfaceHandleList get NULL==pDDLcl");
  1492. for (i = 0; i < MAX_CONTEXT_NUM; i++)
  1493. {
  1494. if (HandleList[i].pDDLcl == pDDLcl)
  1495. {
  1496. DWORD j;
  1497. if (NULL != HandleList[i].dwSurfaceList)
  1498. {
  1499. DBG_D3D((4,"Releasing HandleList[%d].dwSurfaceList[%x] "
  1500. "for pDDLcl %x", i, HandleList[i].dwSurfaceList,
  1501. pDDLcl));
  1502. for (j = 1; j < PtrToUlong(HandleList[i].dwSurfaceList[0]); j++)
  1503. {
  1504. PERMEDIA_D3DTEXTURE* pTexture =
  1505. (PERMEDIA_D3DTEXTURE*)HandleList[i].dwSurfaceList[j];
  1506. if (NULL != pTexture)
  1507. {
  1508. PermediaSurfaceData *pPrivateData=
  1509. pTexture->pTextureSurface;
  1510. if (CHECK_P2_SURFACEDATA_VALIDITY(pPrivateData) &&
  1511. (pPrivateData->fpVidMem))
  1512. {
  1513. TextureCacheManagerRemove(&P2TextureManager,
  1514. pTexture);
  1515. }
  1516. ENGFREEMEM(pTexture);
  1517. }
  1518. }
  1519. ENGFREEMEM(HandleList[i].dwSurfaceList);
  1520. HandleList[i].dwSurfaceList = NULL;
  1521. }
  1522. HandleList[i].pDDLcl = NULL;
  1523. if (NULL != HandleList[i].dwPaletteList)
  1524. {
  1525. DBG_D3D((4,"Releasing dwPaletteList %x for pDDLcl %x",
  1526. HandleList[i].dwPaletteList,pDDLcl));
  1527. for (j = 1; j < PtrToUlong(HandleList[i].dwPaletteList[0]); j++)
  1528. {
  1529. LPVOID pPalette = (LPVOID)HandleList[i].dwPaletteList[j];
  1530. if (NULL != pPalette)
  1531. ENGFREEMEM(pPalette);
  1532. }
  1533. ENGFREEMEM(HandleList[i].dwPaletteList);
  1534. HandleList[i].dwPaletteList = NULL;
  1535. }
  1536. break;
  1537. }
  1538. }
  1539. DBG_D3D((10,"Exiting ReleaseSurfaceHandleList"));
  1540. } // ReleaseSurfaceHandleList
  1541. //-----------------------------Public Routine----------------------------------
  1542. //
  1543. // DWORD D3DGetDriverState
  1544. //
  1545. // This callback is used by both the DirectDraw and Direct3D runtimes to obtain
  1546. // information from the driver about its current state.
  1547. //
  1548. // Parameters
  1549. //
  1550. // lpgdsd
  1551. // pointer to GetDriverState data structure
  1552. //
  1553. // dwFlags
  1554. // Flags to indicate the data required
  1555. // dwhContext
  1556. // The ID of the context for which information
  1557. // is being requested
  1558. // lpdwStates
  1559. // Pointer to the state data to be filled in by the driver
  1560. // dwLength
  1561. // Length of the state data buffer to be filled
  1562. // in by the driver
  1563. // ddRVal
  1564. // Return value
  1565. //
  1566. // Return Value
  1567. //
  1568. // DDHAL_DRIVER_HANDLED
  1569. // DDHAL_DRIVER_NOTHANDLED
  1570. //-----------------------------------------------------------------------------
  1571. DWORD CALLBACK
  1572. D3DGetDriverState( LPDDHAL_GETDRIVERSTATEDATA lpgdsd )
  1573. {
  1574. PERMEDIA_D3DCONTEXT *pContext;
  1575. DBG_D3D((6,"Entering D3DGetDriverState"));
  1576. if (lpgdsd->dwFlags != D3DDEVINFOID_TEXTUREMANAGER)
  1577. {
  1578. DBG_D3D((0,"D3DGetDriverState DEVICEINFOID=%08lx not supported",
  1579. lpgdsd->dwFlags));
  1580. return DDHAL_DRIVER_NOTHANDLED;
  1581. }
  1582. if (lpgdsd->dwLength < sizeof(D3DDEVINFO_TEXTUREMANAGER))
  1583. {
  1584. DBG_D3D((0,"D3DGetDriverState dwLength=%d is not sufficient",
  1585. lpgdsd->dwLength));
  1586. return DDHAL_DRIVER_NOTHANDLED;
  1587. }
  1588. pContext = (PERMEDIA_D3DCONTEXT *)ContextSlots[lpgdsd->dwhContext] ;
  1589. // Check if we got a valid context handle.
  1590. CHK_CONTEXT(pContext, lpgdsd->ddRVal, "D3DGetDriverState");
  1591. TextureCacheManagerGetStats(pContext,
  1592. (LPD3DDEVINFO_TEXTUREMANAGER)lpgdsd->lpdwStates);
  1593. lpgdsd->ddRVal = DD_OK;
  1594. DBG_D3D((6,"Exiitng D3DGetDriverState"));
  1595. return DDHAL_DRIVER_HANDLED;
  1596. } // D3DGetDriverState
  1597. //-----------------------------------------------------------------------------
  1598. //
  1599. // __CreateSurfaceHandle
  1600. //
  1601. // allocate a new surface handle
  1602. //
  1603. // return value
  1604. //
  1605. // DD_OK -- no error
  1606. // DDERR_OUTOFMEMORY -- allocation of texture handle failed
  1607. //
  1608. //-----------------------------------------------------------------------------
  1609. DWORD __CreateSurfaceHandle( PPDev ppdev,
  1610. LPVOID pDDLcl,
  1611. LPDDRAWI_DDRAWSURFACE_LCL lpDDSLcl)
  1612. {
  1613. PPERMEDIA_D3DTEXTURE pTexture;
  1614. DUMPSURFACE(10, lpDDSLcl, NULL);
  1615. if (0 == lpDDSLcl->lpSurfMore->dwSurfaceHandle)
  1616. {
  1617. DBG_D3D((0,"D3DCreateSurfaceEx got 0 surfacehandle dwCaps=%08lx",
  1618. lpDDSLcl->ddsCaps.dwCaps));
  1619. return DD_OK;
  1620. }
  1621. pTexture =
  1622. GetTextureSlot(pDDLcl,lpDDSLcl->lpSurfMore->dwSurfaceHandle);
  1623. if ((0 == lpDDSLcl->lpGbl->fpVidMem) &&
  1624. (DDSCAPS_SYSTEMMEMORY & lpDDSLcl->ddsCaps.dwCaps))
  1625. {
  1626. // this is a system memory destroy notification
  1627. // so go ahead free the slot for this surface if we have it
  1628. if (NULL != pTexture)
  1629. {
  1630. ASSERTDD(HandleList[pTexture->HandleListIndex].dwSurfaceList
  1631. [lpDDSLcl->lpSurfMore->dwSurfaceHandle] == pTexture,
  1632. "__CreateSurfaceHandle: mismatching pTexture in HandleList");
  1633. HandleList[pTexture->HandleListIndex].dwSurfaceList
  1634. [lpDDSLcl->lpSurfMore->dwSurfaceHandle]=0;
  1635. ENGFREEMEM(pTexture);
  1636. DBG_D3D((8,"D3DCreateSurfaceEx freeing handle=%08lx dwCaps=%08lx",
  1637. lpDDSLcl->lpSurfMore->dwSurfaceHandle,lpDDSLcl->ddsCaps.dwCaps));
  1638. }
  1639. return DD_OK;
  1640. }
  1641. if (NULL == pTexture)
  1642. {
  1643. pTexture =
  1644. (PERMEDIA_D3DTEXTURE*)ENGALLOCMEM( FL_ZERO_MEMORY,
  1645. sizeof(PERMEDIA_D3DTEXTURE),
  1646. ALLOC_TAG);
  1647. if (NULL != pTexture)
  1648. {
  1649. if (!SetTextureSlot(pDDLcl,lpDDSLcl,pTexture))
  1650. {
  1651. // Free texture structure since we won't be able to remember it
  1652. // in order to later delete it. We must do it now.
  1653. ENGFREEMEM(pTexture);
  1654. return DDERR_OUTOFMEMORY;
  1655. }
  1656. }
  1657. else
  1658. {
  1659. DBG_D3D((0,"ERROR: Couldn't allocate Texture data mem"));
  1660. return DDERR_OUTOFMEMORY;
  1661. }
  1662. }
  1663. lpDDSLcl->dwReserved1=pTexture->HandleListIndex;
  1664. __InitD3DTextureWithDDSurfInfo(pTexture,lpDDSLcl,ppdev);
  1665. if (pTexture->dwCaps & DDSCAPS_TEXTURE)
  1666. {
  1667. for (int i = 1; i < MAX_CONTEXT_NUM; i++)
  1668. {
  1669. PERMEDIA_D3DCONTEXT *pContext =
  1670. (PERMEDIA_D3DCONTEXT *)ContextSlots[i];
  1671. if (IS_D3DCONTEXT_VALID(pContext))
  1672. {
  1673. DBG_D3D((4," Context 0x%x, Pointer 0x%x",
  1674. (DWORD)i, pContext));
  1675. if ((pContext->pDDLcl == pDDLcl)
  1676. && (pContext->CurrentTextureHandle ==
  1677. lpDDSLcl->lpSurfMore->dwSurfaceHandle)
  1678. )
  1679. {
  1680. // If the texture being swapped is
  1681. // currently being used then we need
  1682. // to change the chip setup to reflect this.
  1683. DIRTY_TEXTURE;
  1684. }
  1685. }
  1686. }
  1687. }
  1688. return DD_OK;
  1689. }
  1690. //-----------------------------------------------------------------------------
  1691. //
  1692. // __CreateSurfaceHandleLoop
  1693. //
  1694. // allocate a list of new surface handles by traversing AttachList
  1695. // recursively and calling __CreateSurfaceHandle()
  1696. // only exceptions are for MIPMAP and CUBMAP, which we only
  1697. // use one handle to the root to represent the whole surface
  1698. // return value
  1699. //
  1700. // DD_OK -- no error
  1701. // DDERR_OUTOFMEMORY -- allocation of texture handle failed
  1702. //
  1703. //-----------------------------------------------------------------------------
  1704. DWORD __CreateSurfaceHandleLoop( PPDev ppdev,
  1705. LPVOID pDDLcl,
  1706. LPDDRAWI_DDRAWSURFACE_LCL lpDDSLclroot,
  1707. LPDDRAWI_DDRAWSURFACE_LCL lpDDSLcl)
  1708. {
  1709. LPATTACHLIST curr;
  1710. DWORD ddRVal=DD_OK;
  1711. // Now allocate the texture data space
  1712. if (0 == lpDDSLcl->lpSurfMore->dwSurfaceHandle)
  1713. {
  1714. DBG_D3D((0,"__CreateSurfaceHandleLoop got 0 handle dwCaps=%08lx",
  1715. lpDDSLcl->ddsCaps.dwCaps));
  1716. return DD_OK;
  1717. }
  1718. if ((0 == lpDDSLcl->lpGbl->dwReserved1) &&
  1719. (DDSCAPS_VIDEOMEMORY & lpDDSLcl->ddsCaps.dwCaps)
  1720. )
  1721. {
  1722. DBG_D3D((4,"__CreateSurfaceHandleLoop got "
  1723. "handle=%08lx dwCaps=%08lx not yet created",
  1724. lpDDSLcl->lpSurfMore->dwSurfaceHandle,lpDDSLcl->ddsCaps.dwCaps));
  1725. return DD_OK;
  1726. }
  1727. DBG_D3D((4,"** In __CreateSurfaceHandleLoop %08lx %08lx %08lx %08lx %x",
  1728. lpDDSLcl->ddsCaps.dwCaps,lpDDSLcl->lpSurfMore->dwSurfaceHandle,
  1729. lpDDSLcl->dwFlags,lpDDSLcl->lpGbl->dwReserved1,
  1730. lpDDSLcl->lpGbl->fpVidMem));
  1731. ddRVal=__CreateSurfaceHandle( ppdev, pDDLcl, lpDDSLcl);
  1732. if (DD_OK != ddRVal)
  1733. {
  1734. return ddRVal;
  1735. }
  1736. // for some surfaces other than MIPMAP or CUBEMAP, such as
  1737. // flipping chains, we make a slot for every surface, as
  1738. // they are not as interleaved
  1739. if ((lpDDSLcl->ddsCaps.dwCaps & DDSCAPS_MIPMAP) ||
  1740. (lpDDSLcl->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_CUBEMAP)
  1741. )
  1742. {
  1743. return DD_OK;
  1744. }
  1745. curr = lpDDSLcl->lpAttachList;
  1746. if (NULL == curr)
  1747. return DD_OK;
  1748. // check if there is another surface attached!
  1749. if (curr->lpLink)
  1750. {
  1751. lpDDSLcl=curr->lpLink->lpAttached;
  1752. if (NULL != lpDDSLcl && lpDDSLcl != lpDDSLclroot)
  1753. {
  1754. ddRVal=__CreateSurfaceHandleLoop( ppdev, pDDLcl,
  1755. lpDDSLclroot, lpDDSLcl);
  1756. if (DD_OK != ddRVal)
  1757. {
  1758. return ddRVal;
  1759. }
  1760. }
  1761. }
  1762. lpDDSLcl=curr->lpAttached;
  1763. if (NULL != lpDDSLcl && lpDDSLcl != lpDDSLclroot)
  1764. ddRVal=__CreateSurfaceHandleLoop( ppdev, pDDLcl,
  1765. lpDDSLclroot, lpDDSLcl);
  1766. return ddRVal;
  1767. }
  1768. //-----------------------------Public Routine----------------------------------
  1769. //
  1770. // DWORD D3DCreateSurfaceEx
  1771. //
  1772. // D3dCreateSurfaceEx creates a Direct3D surface from a DirectDraw surface and
  1773. // associates a requested handle value to it.
  1774. //
  1775. // All Direct3D drivers must support D3dCreateSurfaceEx.
  1776. //
  1777. // D3dCreateSurfaceEx creates an association between a DirectDraw surface and
  1778. // a small integer surface handle. By creating these associations between a
  1779. // handle and a DirectDraw surface, D3dCreateSurfaceEx allows a surface handle
  1780. // to be imbedded in the Direct3D command stream. For example when the
  1781. // D3DDP2OP_TEXBLT command token is sent to D3dDrawPrimitives2 to load a texture
  1782. // map, it uses a source handle and destination handle which were associated
  1783. // with a DirectDraw surface through D3dCreateSurfaceEx.
  1784. //
  1785. // For every DirectDraw surface created under the local DirectDraw object, the
  1786. // runtime generates a valid handle that uniquely identifies the surface and
  1787. // places it in pcsxd->lpDDSLcl->lpSurfMore->dwSurfaceHandle. This handle value
  1788. // is also used with the D3DRENDERSTATE_TEXTUREHANDLE render state to enable
  1789. // texturing, and with the D3DDP2OP_SETRENDERTARGET and D3DDP2OP_CLEAR commands
  1790. // to set and/or clear new rendering and depth buffers. The driver should fail
  1791. // the call and return DDHAL_DRIVER_HANDLE if it cannot create the Direct3D
  1792. // surface.
  1793. //
  1794. // As appropriate, the driver should also store any surface-related information
  1795. // that it will subsequently need when using the surface. The driver must create
  1796. // a new surface table for each new lpDDLcl and implicitly grow the table when
  1797. // necessary to accommodate more surfaces. Typically this is done with an
  1798. // exponential growth algorithm so that you don't have to grow the table too
  1799. // often. Direct3D calls D3dCreateSurfaceEx after the surface is created by
  1800. // DirectDraw by request of the Direct3D runtime or the application.
  1801. //
  1802. // Parameters
  1803. //
  1804. // lpcsxd
  1805. // pointer to CreateSurfaceEx structure that contains the information
  1806. // required for the driver to create the surface (described below).
  1807. //
  1808. // dwFlags
  1809. // Currently unused
  1810. // lpDDLcl
  1811. // Handle to the DirectDraw object created by the application.
  1812. // This is the scope within which the lpDDSLcl handles exist.
  1813. // A DD_DIRECTDRAW_LOCAL structure describes the driver.
  1814. // lpDDSLcl
  1815. // Handle to the DirectDraw surface we are being asked to
  1816. // create for Direct3D. These handles are unique within each
  1817. // different DD_DIRECTDRAW_LOCAL. A DD_SURFACE_LOCAL structure
  1818. // represents the created surface object.
  1819. // ddRVal
  1820. // Specifies the location in which the driver writes the return
  1821. // value of the D3dCreateSurfaceEx callback. A return code of
  1822. // DD_OK indicates success.
  1823. //
  1824. // Return Value
  1825. //
  1826. // DDHAL_DRIVER_HANDLE
  1827. // DDHAL_DRIVER_NOTHANDLE
  1828. //
  1829. //-----------------------------------------------------------------------------
  1830. DWORD CALLBACK
  1831. D3DCreateSurfaceEx( LPDDHAL_CREATESURFACEEXDATA lpcsxd )
  1832. {
  1833. PPERMEDIA_D3DTEXTURE pTexture;
  1834. LPVOID pDDLcl= (LPVOID)lpcsxd->lpDDLcl;
  1835. LPDDRAWI_DDRAWSURFACE_LCL lpDDSLcl=lpcsxd->lpDDSLcl;
  1836. LPATTACHLIST curr;
  1837. DBG_D3D((6,"Entering D3DCreateSurfaceEx"));
  1838. lpcsxd->ddRVal = DD_OK;
  1839. if (NULL == lpDDSLcl || NULL == pDDLcl)
  1840. {
  1841. DBG_D3D((0,"D3DCreateSurfaceEx received 0 lpDDLcl or lpDDSLcl pointer"));
  1842. return DDHAL_DRIVER_HANDLED;
  1843. }
  1844. // We check that what we are handling is a texture, zbuffer or a rendering
  1845. // target buffer. We don't check if it is however stored in local video
  1846. // memory since it might also be a system memory texture that we will later
  1847. // blt with __TextureBlt.
  1848. // also if your driver supports DDSCAPS_EXECUTEBUFFER create itself, it must
  1849. // process DDSCAPS_EXECUTEBUFFER here as well.
  1850. if (!(lpDDSLcl->ddsCaps.dwCaps &
  1851. (DDSCAPS_TEXTURE |
  1852. DDSCAPS_3DDEVICE |
  1853. DDSCAPS_ZBUFFER))
  1854. )
  1855. {
  1856. DBG_D3D((2,"D3DCreateSurfaceEx w/o "
  1857. "DDSCAPS_TEXTURE/3DDEVICE/ZBUFFER Ignored"
  1858. "dwCaps=%08lx dwSurfaceHandle=%08lx",
  1859. lpDDSLcl->ddsCaps.dwCaps,
  1860. lpDDSLcl->lpSurfMore->dwSurfaceHandle));
  1861. return DDHAL_DRIVER_HANDLED;
  1862. }
  1863. DBG_D3D((4,"Entering D3DCreateSurfaceEx handle=%08lx",
  1864. lpDDSLcl->lpSurfMore->dwSurfaceHandle));
  1865. PPDev ppdev=(PPDev)lpcsxd->lpDDLcl->lpGbl->dhpdev;
  1866. PERMEDIA_DEFS(ppdev);
  1867. //@@BEGIN_DDKSPLIT
  1868. #if MULTITHREADED
  1869. if(ppdev->ulLockCount)
  1870. {
  1871. DBG_D3D((MT_LOG_LEVEL, "D3DCreateSurfaceEx: re-entry! %d", ppdev->ulLockCount));
  1872. }
  1873. EngAcquireSemaphore(ppdev->hsemLock);
  1874. ppdev->ulLockCount++;
  1875. #endif
  1876. //@@END_DDKSPLIT
  1877. // Now allocate the texture data space
  1878. lpcsxd->ddRVal = __CreateSurfaceHandleLoop( ppdev, pDDLcl, lpDDSLcl, lpDDSLcl);
  1879. DBG_D3D((4,"Exiting D3DCreateSurfaceEx"));
  1880. //@@BEGIN_DDKSPLIT
  1881. #if MULTITHREADED
  1882. ppdev->ulLockCount--;
  1883. EngReleaseSemaphore(ppdev->hsemLock);
  1884. #endif
  1885. //@@END_DDKSPLIT
  1886. return DDHAL_DRIVER_HANDLED;
  1887. } // D3DCreateSurfaceEx
  1888. //-----------------------------Public Routine----------------------------------
  1889. //
  1890. // DWORD D3DDestroyDDLocal
  1891. //
  1892. // D3dDestroyDDLocal destroys all the Direct3D surfaces previously created by
  1893. // D3DCreateSurfaceEx that belong to the same given local DirectDraw object.
  1894. //
  1895. // All Direct3D drivers must support D3dDestroyDDLocal.
  1896. // Direct3D calls D3dDestroyDDLocal when the application indicates that the
  1897. // Direct3D context is no longer required and it will be destroyed along with
  1898. // all surfaces associated to it. The association comes through the pointer to
  1899. // the local DirectDraw object. The driver must free any memory that the
  1900. // driver's D3dCreateSurfaceExDDK_D3dCreateSurfaceEx_GG callback allocated for
  1901. // each surface if necessary. The driver should not destroy the DirectDraw
  1902. // surfaces associated with these Direct3D surfaces; this is the application's
  1903. // responsibility.
  1904. //
  1905. // Parameters
  1906. //
  1907. // lpdddd
  1908. // Pointer to the DestoryLocalDD structure that contains the
  1909. // information required for the driver to destroy the surfaces.
  1910. //
  1911. // dwFlags
  1912. // Currently unused
  1913. // pDDLcl
  1914. // Pointer to the local Direct Draw object which serves as a
  1915. // reference for all the D3D surfaces that have to be destroyed.
  1916. // ddRVal
  1917. // Specifies the location in which the driver writes the return
  1918. // value of D3dDestroyDDLocal. A return code of DD_OK indicates
  1919. // success.
  1920. //
  1921. // Return Value
  1922. //
  1923. // DDHAL_DRIVER_HANDLED
  1924. // DDHAL_DRIVER_NOTHANDLED
  1925. //-----------------------------------------------------------------------------
  1926. DWORD CALLBACK
  1927. D3DDestroyDDLocal( LPDDHAL_DESTROYDDLOCALDATA lpdddd )
  1928. {
  1929. DBG_D3D((6,"Entering D3DDestroyDDLocal"));
  1930. //@@BEGIN_DDKSPLIT
  1931. #if MULTITHREADED
  1932. PPDev ppdev=(PPDev)lpdddd->pDDLcl->lpGbl->dhpdev;
  1933. if(ppdev->ulLockCount)
  1934. {
  1935. DBG_D3D((MT_LOG_LEVEL, "D3DCreateSurfaceEx: re-entry! %d", ppdev->ulLockCount));
  1936. }
  1937. EngAcquireSemaphore(ppdev->hsemLock);
  1938. ppdev->ulLockCount++;
  1939. #endif
  1940. //@@END_DDKSPLIT
  1941. ReleaseSurfaceHandleList(LPVOID(lpdddd->pDDLcl));
  1942. lpdddd->ddRVal = DD_OK;
  1943. DBG_D3D((6,"Exiting D3DDestroyDDLocal"));
  1944. //@@BEGIN_DDKSPLIT
  1945. #if MULTITHREADED
  1946. ppdev->ulLockCount--;
  1947. EngReleaseSemaphore(ppdev->hsemLock);
  1948. #endif
  1949. //@@END_DDKSPLIT
  1950. return DDHAL_DRIVER_HANDLED;
  1951. } // D3DDestroyDDLocal
  1952. //-----------------------------Public Routine----------------------------------
  1953. //
  1954. // DdSetColorkey
  1955. //
  1956. // DirectDraw SetColorkey callback
  1957. //
  1958. // Parameters
  1959. // lpSetColorKey
  1960. // Pointer to the LPDDHAL_SETCOLORKEYDATA parameters structure
  1961. //
  1962. // lpDDSurface
  1963. // Surface struct
  1964. // dwFlags
  1965. // Flags
  1966. // ckNew
  1967. // New chroma key color values
  1968. // ddRVal
  1969. // Return value
  1970. // SetColorKey
  1971. // Unused: Win95 compatibility
  1972. //
  1973. //-----------------------------------------------------------------------------
  1974. DWORD CALLBACK
  1975. DdSetColorKey(LPDDHAL_SETCOLORKEYDATA lpSetColorKey)
  1976. {
  1977. DWORD dwSurfaceHandle =
  1978. lpSetColorKey->lpDDSurface->lpSurfMore->dwSurfaceHandle;
  1979. DWORD index = (DWORD)lpSetColorKey->lpDDSurface->dwReserved1;
  1980. DBG_D3D((6,"Entering DdSetColorKey dwSurfaceHandle=%d index=%d",
  1981. dwSurfaceHandle, index));
  1982. lpSetColorKey->ddRVal = DD_OK;
  1983. // We don't have to do anything for normal blt source colour keys:
  1984. if (!(DDSCAPS_TEXTURE & lpSetColorKey->lpDDSurface->ddsCaps.dwCaps) ||
  1985. !(DDSCAPS_VIDEOMEMORY & lpSetColorKey->lpDDSurface->ddsCaps.dwCaps)
  1986. )
  1987. {
  1988. return(DDHAL_DRIVER_HANDLED);
  1989. }
  1990. if (0 != dwSurfaceHandle && NULL != HandleList[index].dwSurfaceList)
  1991. {
  1992. PERMEDIA_D3DTEXTURE *pTexture =
  1993. HandleList[index].dwSurfaceList[dwSurfaceHandle];
  1994. ASSERTDD(PtrToUlong(HandleList[index].dwSurfaceList[0]) > dwSurfaceHandle,
  1995. "SetColorKey: incorrect dwSurfaceHandle");
  1996. if (NULL != pTexture)
  1997. {
  1998. DBG_D3D((4, "DdSetColorKey surface=%08lx KeyLow=%08lx",
  1999. dwSurfaceHandle,pTexture->dwKeyLow));
  2000. pTexture->dwFlags |= DDRAWISURF_HASCKEYSRCBLT;
  2001. pTexture->dwKeyLow = lpSetColorKey->ckNew.dwColorSpaceLowValue;
  2002. pTexture->dwKeyHigh = lpSetColorKey->ckNew.dwColorSpaceHighValue;
  2003. }
  2004. }
  2005. else
  2006. {
  2007. lpSetColorKey->ddRVal = DDERR_INVALIDPARAMS;
  2008. }
  2009. DBG_D3D((6,"Exiting DdSetColorKey"));
  2010. return DDHAL_DRIVER_HANDLED;
  2011. } // DdSetColorKey
  2012. //@@BEGIN_DDKSPLIT
  2013. #if MULTITHREADED
  2014. //-----------------------------------------------------------------------------
  2015. //
  2016. // Multithread support wrappers for D3D callback functions
  2017. //
  2018. //-----------------------------------------------------------------------------
  2019. //DWORD CALLBACK MtD3DDrawPrimitives2(LPD3DNTHAL_DRAWPRIMITIVES2DATA pdp2);,
  2020. WRAPMTDXCALLBACK(D3D, D3DDrawPrimitives2, LPD3DNTHAL_DRAWPRIMITIVES2DATA, pdp2,
  2021. ((PERMEDIA_D3DCONTEXT *)ContextSlots[pdp2->dwhContext])->ppdev)
  2022. //DWORD CALLBACK MtDdSetColorKey(LPDDHAL_SETCOLORKEYDATA lpSetColorKey);
  2023. WRAPMTDXCALLBACK(D3D, DdSetColorKey, LPDDHAL_SETCOLORKEYDATA, lpSetColorKey,
  2024. lpSetColorKey->lpDD->dhpdev);
  2025. #endif MULTITHREADED
  2026. //@@END_DDKSPLIT