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.

1834 lines
72 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * **************************
  4. * * DirectDraw SAMPLE CODE *
  5. * **************************
  6. *
  7. * Module Name: ddsurf.c
  8. *
  9. * Content: DirectDraw surfaces creation/destructions callbacks
  10. *
  11. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. // This file needs the surface format table
  15. #include "glint.h"
  16. #include "dma.h"
  17. // This enum is used to lookup the correct entry in the table
  18. // for all the surface types the HAL cares about
  19. typedef enum tagDeviceFormatNum
  20. {
  21. HAL_8888_ALPHA = 0,
  22. HAL_8888_NOALPHA = 1,
  23. HAL_5551_ALPHA = 2,
  24. HAL_5551_NOALPHA = 3,
  25. HAL_4444 = 4,
  26. HAL_332 = 10,
  27. HAL_2321 = 18,
  28. HAL_CI8 = 28,
  29. HAL_CI4 = 29,
  30. HAL_565 = 30,
  31. HAL_YUV444 = 34,
  32. HAL_YUV422 = 35,
  33. HAL_L8 = 36,
  34. HAL_A8L8 = 37,
  35. HAL_A4L4 = 38,
  36. HAL_A8 = 39,
  37. HAL_MVCA = 40,
  38. HAL_MVSU = 41,
  39. HAL_MVSB = 42,
  40. HAL_UNKNOWN = 255,
  41. } DeviceFormatNum;
  42. static P3_SURF_FORMAT SurfaceFormats[MAX_SURFACE_FORMATS] =
  43. {
  44. // If there are multiple formats, the one with the alpha is listed first.
  45. // Format 0 (32 bit 8888) // Always 3 components for 888(8) textures. Red Green Blue Alpha bAlpha, P3RX Filter format
  46. /* 0 */ {SURF_8888, 32, __GLINT_32BITPIXEL, RGBA_COMPONENTS, LOG_2_32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, TRUE, SURF_FILTER_8888_OR_YUV, SURF_DITHER_8888, "R8G8B8A8" },
  47. /* 1 */ {SURF_8888, 32, __GLINT_32BITPIXEL, RGBA_COMPONENTS, LOG_2_32, 0xFF0000, 0xFF00, 0xFF, 0x00000000, FALSE, SURF_FILTER_888, SURF_DITHER_8888, "R8G8B8x8" },
  48. // Format 1 (16 bit 5551)
  49. /* 2 */ {SURF_5551_FRONT, 16, __GLINT_16BITPIXEL, RGBA_COMPONENTS, LOG_2_16, 0x7C00, 0x03E0, 0x001F, 0x8000, TRUE, SURF_FILTER_5551, SURF_DITHER_5551, "R5G5B5A1" },
  50. /* 3 */ {SURF_5551_FRONT, 16, __GLINT_16BITPIXEL, RGB_COMPONENTS, LOG_2_16, 0x7C00, 0x03E0, 0x001F, 0x0, FALSE, SURF_FILTER_5551, SURF_DITHER_5551, "R5G5B5x1" },
  51. // Format 2 (16 bit 4444)
  52. /* 4 */ {SURF_4444, 16, __GLINT_16BITPIXEL, RGBA_COMPONENTS, LOG_2_16, 0xF00, 0xF0, 0xF, 0xF000, TRUE, SURF_FILTER_4444, SURF_DITHER_4444, "R4G4B4A4" },
  53. /* 5 */ {SURF_4444, 16, __GLINT_16BITPIXEL, RGBA_COMPONENTS, LOG_2_16, 0xF00, 0xF0, 0xF, 0xF000, TRUE, SURF_FILTER_4444, SURF_DITHER_4444, "R4G4B4x4" },
  54. // Format 3 (16 bit 4444 Front)
  55. /* 6 */ {SURF_4444_FRONT, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_4444, SURF_DITHER_4444, "R4G4B4A4" },
  56. /* 7 */ {SURF_4444_FRONT, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_4444, SURF_DITHER_4444, "R4G4B4x4" },
  57. // Format 4 (16 bit 4444 Back)
  58. /* 8 */ {SURF_4444_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_4444, SURF_DITHER_4444, "R4G4B4A4" },
  59. /* 9 */ {SURF_4444_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_4444, SURF_DITHER_4444, "R4G4B4x4" },
  60. // Format 5 (8 bit 332 Front)
  61. /* 10 */ {SURF_332_FRONT, 8, __GLINT_8BITPIXEL, RGB_COMPONENTS, LOG_2_8, 0xE0, 0x1C, 0x3, 0, FALSE, SURF_FILTER_332, SURF_DITHER_332, "R3G3B2" },
  62. /* 11 */ {SURF_332_FRONT, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_332, SURF_DITHER_332, "R3G3B2" },
  63. // Format 6 (8 bit 332 back)
  64. /* 12 */ {SURF_332_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_332, SURF_DITHER_332, "R3G3B2" },
  65. /* 13 */ {SURF_332_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_332, SURF_DITHER_332, "R3G3B2" },
  66. // Format 7 (4 bit 121 front)
  67. /* 14 */ {SURF_121_FRONT, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R1G2B1" },
  68. /* 15 */ {SURF_121_FRONT, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R1G2B1" },
  69. // Format 8 (4 bit 121 back)
  70. /* 16 */ {SURF_121_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R1G2B1" },
  71. /* 17 */ {SURF_121_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R1G2B1" },
  72. // Format 9 (8 bit 2321 front)
  73. /* 18 */ {SURF_2321_FRONT, 8, __GLINT_8BITPIXEL, RGBA_COMPONENTS, LOG_2_8, 0xC0, 0x38, 0x6, 0x1, TRUE, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R2G3B2A1" },
  74. /* 19 */ {SURF_2321_FRONT, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R2G3B2x1" },
  75. // Format 10 (8 bit 2321 back)
  76. /* 20 */ {SURF_2321_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R2G3B2A1" },
  77. /* 21 */ {SURF_2321_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R2G3B2x1" },
  78. // Format 11 (8 bit 232 front off)
  79. /* 22 */ {SURF_232_FRONTOFF, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R2G3B2x1" },
  80. /* 23 */ {SURF_232_FRONTOFF, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R2G3B2x1" },
  81. // Format 12 (8 bit 232 back off)
  82. /* 24 */ {SURF_232_BACKOFF, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R2G3B2x1" },
  83. /* 25 */ {SURF_232_BACKOFF, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_INVALID, SURF_DITHER_INVALID, "R2G3B2x1" },
  84. // Format 13 (5551 back)
  85. /* 26 */ {SURF_5551_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_5551, SURF_DITHER_5551, "R5G5B5A1" },
  86. /* 27 */ {SURF_5551_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_5551, SURF_DITHER_5551, "R5G5B5x1" },
  87. // Format 14 (CI8)
  88. /* 28 */ {SURF_CI8, 8, __GLINT_8BITPIXEL, RGBA_COMPONENTS, LOG_2_8, 0, 0, 0, 0, TRUE, SURF_FILTER_8888_OR_YUV, SURF_DITHER_I8, "I8" },
  89. // Format 15 (CI4)
  90. /* 29 */ {SURF_CI4, 4, __GLINT_4BITPIXEL, RGBA_COMPONENTS, LOG_2_4, 0, 0, 0, 0, TRUE, SURF_FILTER_8888_OR_YUV, SURF_DITHER_INVALID, "I4" },
  91. // Format 16 (565 front)
  92. /* 30 */ {SURF_565_FRONT, 16, __GLINT_16BITPIXEL, RGB_COMPONENTS, LOG_2_16, 0xF800, 0x07E0, 0x001F, 0, FALSE, SURF_FILTER_565, SURF_DITHER_565, "R5G6B5" },
  93. /* 31 */ {SURF_565_FRONT, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_565, SURF_DITHER_565, "R5G6B5" },
  94. // Format 17 (565 back)
  95. /* 32 */ {SURF_565_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_565, SURF_DITHER_565, "R5G6B5" },
  96. /* 33 */ {SURF_565_BACK, 0, 0, COMPONENTS_DONT_CARE, 0, 0, 0, 0, 0, 0, SURF_FILTER_565, SURF_DITHER_565, "R5G6B5" },
  97. // Format 18 (YUV 444)
  98. /* 34 */ {SURF_YUV444, 32, __GLINT_16BITPIXEL, RGBA_COMPONENTS, LOG_2_16, 0, 0, 0, 0, TRUE, SURF_FILTER_8888_OR_YUV, SURF_DITHER_INVALID, "YUV444" },
  99. // Format 19 (YUV 422)
  100. /* 35 */ {SURF_YUV422, 16, __GLINT_16BITPIXEL, RGB_COMPONENTS, LOG_2_32, 0, 0, 0, 0, FALSE, SURF_FILTER_8888_OR_YUV, SURF_DITHER_INVALID, "YUV422" },
  101. // Format 100 (L8)
  102. /* 36 */ {SURF_L8, 8, __GLINT_8BITPIXEL, RGB_COMPONENTS, LOG_2_8, 0, 0, 0, 0, FALSE, SURF_FILTER_L8, SURF_DITHER_INVALID, "L8" },
  103. // Format 101 (A8L8)
  104. /* 37 */ {SURF_A8L8, 16, __GLINT_16BITPIXEL, RGB_COMPONENTS, LOG_2_16, 0, 0, 0, 0, TRUE, SURF_FILTER_A8L8, SURF_DITHER_INVALID, "A8L8" },
  105. // Format 102 (A4L4)
  106. /* 38 */ {SURF_A4L4, 16, __GLINT_8BITPIXEL, RGB_COMPONENTS, LOG_2_8, 0, 0, 0, 0, TRUE, SURF_FILTER_A4L4, SURF_DITHER_INVALID, "A4L4" },
  107. // Format 103 (A8)
  108. /* 39 */ {SURF_A8, 8, __GLINT_8BITPIXEL, RGB_COMPONENTS, LOG_2_8, 0, 0, 0, 0, TRUE, SURF_FILTER_A8, SURF_DITHER_INVALID, "A8" },
  109. // Format 104 (A8) MVCA
  110. /* 40 */ {SURF_MVCA, 32, __GLINT_32BITPIXEL, RGB_COMPONENTS, LOG_2_32, 0, 0, 0, 0, TRUE, SURF_FILTER_8888_OR_YUV, SURF_DITHER_INVALID, "MVCA" },
  111. // Format 105 (A8) MVSU
  112. /* 41 */ {SURF_MVSU, 32, __GLINT_32BITPIXEL, RGB_COMPONENTS, LOG_2_32, 0, 0, 0, 0, TRUE, SURF_FILTER_8888_OR_YUV, SURF_DITHER_INVALID, "MVSU" },
  113. // Format 106 (A8) MVSB
  114. /* 42 */ {SURF_MVSB, 32, __GLINT_32BITPIXEL, RGB_COMPONENTS, LOG_2_32, 0, 0, 0, 0, TRUE, SURF_FILTER_8888_OR_YUV, SURF_DITHER_INVALID, "MVSB" }
  115. };
  116. #define MAKE_DWORD_ALIGNED(n) ( ((n) % 4) ? ((n) + 4 - ((n) % 4)) : (n) )
  117. #define MAKE_QWORD_ALIGNED(n) ( ((n) % 8) ? ((n) + 8 - ((n) % 8)) : (n) )
  118. //-----------------------------------------------------------------------------
  119. //
  120. // _DD_SUR_GetSurfaceFormat
  121. //
  122. //-----------------------------------------------------------------------------
  123. P3_SURF_FORMAT*
  124. _DD_SUR_GetSurfaceFormat(
  125. LPDDRAWI_DDRAWSURFACE_LCL pLcl)
  126. {
  127. DeviceFormatNum HALDeviceFormat = HAL_UNKNOWN; // The default
  128. if (pLcl)
  129. {
  130. DDPIXELFORMAT* pPixFormat = DDSurf_GetPixelFormat(pLcl);
  131. if (pPixFormat->dwFlags & DDPF_FOURCC)
  132. {
  133. switch( pPixFormat->dwFourCC)
  134. {
  135. case FOURCC_MVCA:
  136. HALDeviceFormat = HAL_MVCA;
  137. break;
  138. case FOURCC_MVSU:
  139. HALDeviceFormat = HAL_MVSU;
  140. break;
  141. case FOURCC_MVSB:
  142. HALDeviceFormat = HAL_MVSB;
  143. break;
  144. case FOURCC_YUV422:
  145. HALDeviceFormat = HAL_YUV422;
  146. break;
  147. case FOURCC_YUV411:
  148. HALDeviceFormat = HAL_YUV444;
  149. break;
  150. } //switch
  151. }
  152. else if (pPixFormat->dwFlags & DDPF_PALETTEINDEXED4)
  153. {
  154. HALDeviceFormat = HAL_CI4;
  155. }
  156. else if (pPixFormat->dwFlags & DDPF_PALETTEINDEXED8)
  157. {
  158. HALDeviceFormat = HAL_CI8;
  159. }
  160. else if (pPixFormat->dwFlags & DDPF_LUMINANCE)
  161. {
  162. switch(pPixFormat->dwRGBBitCount)
  163. {
  164. case 8:
  165. if (pPixFormat->dwFlags & DDPF_ALPHAPIXELS)
  166. {
  167. HALDeviceFormat = HAL_A4L4;
  168. }
  169. else
  170. {
  171. HALDeviceFormat = HAL_L8;
  172. }
  173. break;
  174. case 16:
  175. HALDeviceFormat = HAL_A8L8;
  176. break;
  177. default:
  178. HALDeviceFormat = HAL_UNKNOWN;
  179. break;
  180. } // switch
  181. }
  182. else if (pPixFormat->dwFlags & DDPF_ALPHA)
  183. {
  184. // Alpha only format
  185. switch(pPixFormat->dwAlphaBitDepth)
  186. {
  187. case 8:
  188. HALDeviceFormat = HAL_A8;
  189. break;
  190. default:
  191. HALDeviceFormat = HAL_UNKNOWN;
  192. break;
  193. }
  194. }
  195. else
  196. {
  197. switch(pPixFormat->dwRGBBitCount)
  198. {
  199. case 32:
  200. case 24:
  201. if (pPixFormat->dwRGBAlphaBitMask != 0)
  202. {
  203. HALDeviceFormat = HAL_8888_ALPHA;
  204. }
  205. else
  206. {
  207. HALDeviceFormat = HAL_8888_NOALPHA;
  208. }
  209. break;
  210. case 16:
  211. switch (pPixFormat->dwRBitMask)
  212. {
  213. case 0xf00:
  214. HALDeviceFormat = HAL_4444;
  215. break;
  216. case 0x7c00:
  217. if (pPixFormat->dwRGBAlphaBitMask != 0)
  218. {
  219. HALDeviceFormat = HAL_5551_ALPHA;
  220. }
  221. else
  222. {
  223. HALDeviceFormat = HAL_5551_NOALPHA;
  224. }
  225. break;
  226. default:
  227. HALDeviceFormat = HAL_565;
  228. break;
  229. }
  230. break;
  231. case 8:
  232. if (pPixFormat->dwRBitMask != 0xE0)
  233. {
  234. HALDeviceFormat = HAL_2321;
  235. }
  236. else
  237. {
  238. HALDeviceFormat = HAL_332;
  239. }
  240. break;
  241. case 0:
  242. HALDeviceFormat = HAL_CI8;
  243. break;
  244. default:
  245. DISPDBG((ERRLVL,"_DD_SUR_GetSurfaceFormat: "
  246. "Invalid Surface Format"));
  247. break;
  248. } // switch
  249. } // if
  250. }
  251. #if DBG
  252. if (HALDeviceFormat == HAL_UNKNOWN)
  253. {
  254. DISPDBG((ERRLVL,"ERROR: Failed to pick a valid surface format!"));
  255. }
  256. if(SurfaceFormats[HALDeviceFormat].dwBitsPerPixel == 0)
  257. {
  258. DISPDBG((ERRLVL,"ERROR: Chosen surface format that isn't defined "
  259. "in the table!"));
  260. }
  261. #endif // DBG
  262. if (HALDeviceFormat == HAL_UNKNOWN)
  263. {
  264. // Don't know what it is - return a valid type.
  265. return &SurfaceFormats[0];
  266. }
  267. else
  268. {
  269. // Return a pointer to the correct line in the table
  270. return &SurfaceFormats[HALDeviceFormat];
  271. }
  272. } // _DD_SUR_GetSurfaceFormat
  273. //---------------------------------------------------------------------------
  274. // BOOL __SUR_bComparePixelFormat
  275. //
  276. // Function used to compare 2 pixels formats for equality. This is a
  277. // helper function to __SUR_bCheckTextureFormat. A return value of TRUE
  278. // indicates equality
  279. //
  280. //---------------------------------------------------------------------------
  281. BOOL
  282. __SUR_bComparePixelFormat(
  283. LPDDPIXELFORMAT lpddpf1,
  284. LPDDPIXELFORMAT lpddpf2)
  285. {
  286. if (lpddpf1->dwFlags != lpddpf2->dwFlags)
  287. {
  288. return FALSE;
  289. }
  290. // same bitcount for non-YUV surfaces?
  291. if (!(lpddpf1->dwFlags & (DDPF_YUV | DDPF_FOURCC)))
  292. {
  293. if (lpddpf1->dwRGBBitCount != lpddpf2->dwRGBBitCount )
  294. {
  295. return FALSE;
  296. }
  297. }
  298. // same RGB properties?
  299. if (lpddpf1->dwFlags & DDPF_RGB)
  300. {
  301. if ((lpddpf1->dwRBitMask != lpddpf2->dwRBitMask) ||
  302. (lpddpf1->dwGBitMask != lpddpf2->dwGBitMask) ||
  303. (lpddpf1->dwBBitMask != lpddpf2->dwBBitMask) ||
  304. (lpddpf1->dwRGBAlphaBitMask != lpddpf2->dwRGBAlphaBitMask))
  305. {
  306. return FALSE;
  307. }
  308. }
  309. // same YUV properties?
  310. if (lpddpf1->dwFlags & DDPF_YUV)
  311. {
  312. if ((lpddpf1->dwFourCC != lpddpf2->dwFourCC) ||
  313. (lpddpf1->dwYUVBitCount != lpddpf2->dwYUVBitCount) ||
  314. (lpddpf1->dwYBitMask != lpddpf2->dwYBitMask) ||
  315. (lpddpf1->dwUBitMask != lpddpf2->dwUBitMask) ||
  316. (lpddpf1->dwVBitMask != lpddpf2->dwVBitMask) ||
  317. (lpddpf1->dwYUVAlphaBitMask != lpddpf2->dwYUVAlphaBitMask))
  318. {
  319. return FALSE;
  320. }
  321. }
  322. else if (lpddpf1->dwFlags & DDPF_FOURCC)
  323. {
  324. if (lpddpf1->dwFourCC != lpddpf2->dwFourCC)
  325. {
  326. return FALSE;
  327. }
  328. }
  329. // If Interleaved Z then check Z bit masks are the same
  330. if (lpddpf1->dwFlags & DDPF_ZPIXELS)
  331. {
  332. if (lpddpf1->dwRGBZBitMask != lpddpf2->dwRGBZBitMask)
  333. {
  334. return FALSE;
  335. }
  336. }
  337. return TRUE;
  338. } // __SUR_bComparePixelFormat
  339. //---------------------------------------------------------------------------
  340. //
  341. // BOOL __SUR_bCheckTextureFormat
  342. //
  343. // Function used to determine if a texture format is supported. It traverses
  344. // the deviceTextureFormats list. We use this in DdCanCreateSurface. A
  345. // return value of TRUE indicates that we do support the requested texture
  346. // format.
  347. //
  348. //---------------------------------------------------------------------------
  349. BOOL
  350. __SUR_bCheckTextureFormat(
  351. P3_THUNKEDDATA *pThisDisplay,
  352. LPDDPIXELFORMAT lpddpf)
  353. {
  354. DWORD i;
  355. // Run the list for a matching format , we already built the list (when
  356. // the driver was loaded) and stored it in pThisDisplay with
  357. // __D3D_BuildTextureFormatsP3 in _D3DHALCreateDriver (d3d.c)
  358. // Notice the special handling for paletted textures as described in
  359. // __D3D_BuildTextureFormatsP3 (thats why we loop until <= , not just
  360. // until < ).
  361. for (i=0; i <= pThisDisplay->dwNumTextureFormats; i++)
  362. {
  363. if (__SUR_bComparePixelFormat(
  364. lpddpf,
  365. &pThisDisplay->TextureFormats[i].ddpfPixelFormat))
  366. {
  367. return TRUE;
  368. }
  369. }
  370. return FALSE;
  371. } // __SUR_bCheckTextureFormat
  372. //---------------------------------------------------------------------------
  373. //
  374. // DWORD __SUR_bSurfPlacement
  375. //
  376. // Function used to determine if a surface should be placed at the front or
  377. // at the back of our video memory heap.
  378. // Returns the MEM3DL_FRONT and MEM3DL_BACK values.
  379. //
  380. //---------------------------------------------------------------------------
  381. DWORD
  382. __SUR_bSurfPlacement(
  383. LPDDRAWI_DDRAWSURFACE_LCL psurf,
  384. DDSURFACEDESC *lpDDSurfaceDesc)
  385. {
  386. static BOOL bBufferToggle = TRUE;
  387. DWORD dwResult;
  388. if (psurf->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
  389. {
  390. DWORD dwTexturePlacement;
  391. // They might have passed a DDSD2 in a DDSD1 structure.
  392. if (lpDDSurfaceDesc && (lpDDSurfaceDesc->dwSize ==
  393. sizeof(DDSURFACEDESC2)))
  394. {
  395. DDSURFACEDESC2* pDesc2 =
  396. (DDSURFACEDESC2*)lpDDSurfaceDesc;
  397. // Check for the application hint on texture stage placement
  398. if (!(pDesc2->ddsCaps.dwCaps & DDSCAPS_MIPMAP))
  399. {
  400. if (pDesc2->dwFlags & DDSD_TEXTURESTAGE)
  401. {
  402. dwTexturePlacement = pDesc2->dwTextureStage;
  403. // Put it somewhere sensible if it
  404. // is in a large stage number
  405. if (dwTexturePlacement > 1)
  406. {
  407. // Toggle all entries above 1 so that they
  408. // jump between banks.
  409. dwTexturePlacement =
  410. (dwTexturePlacement ^ 1) & 0x1;
  411. }
  412. }
  413. else
  414. {
  415. // No stage hint. PingPong
  416. dwTexturePlacement = bBufferToggle;
  417. bBufferToggle = !bBufferToggle;
  418. }
  419. }
  420. else
  421. {
  422. // No stage hint. PingPong
  423. dwTexturePlacement = bBufferToggle;
  424. bBufferToggle = !bBufferToggle;
  425. }
  426. }
  427. else
  428. {
  429. // No DDSD2, PingPong
  430. dwTexturePlacement = bBufferToggle;
  431. bBufferToggle = !bBufferToggle;
  432. }
  433. // Jump up and down in the one heap
  434. if (dwTexturePlacement == 0)
  435. {
  436. dwResult = MEM3DL_FRONT;
  437. }
  438. else
  439. {
  440. dwResult = MEM3DL_BACK;
  441. }
  442. }
  443. // Not a texture
  444. else
  445. {
  446. dwResult = MEM3DL_FRONT;
  447. }
  448. return dwResult;
  449. } // __SUR_bSurfPlacement
  450. //-----------------------------Public Routine----------------------------------
  451. //
  452. // DdCanCreateSurface
  453. //
  454. // Indicates whether the driver can create a surface of the specified
  455. // surface description
  456. //
  457. // DdCanCreateSurface should check the surface description to which
  458. // lpDDSurfaceDesc points to determine if the driver can support the format and
  459. // capabilities of the requested surface for the mode that the driver is
  460. // currently in. The driver should return DD_OK in ddRVal if it supports the
  461. // surface; otherwise, it should return the DDERR_Xxx error code that best
  462. // describes why it does not support the surface.
  463. //
  464. // The bIsDifferentPixelFormat member is unreliable for z-buffers. Drivers
  465. // should use bIsDifferentPixelFormat only when they have first checked that
  466. // the specified surface is not a z-buffer. Drivers can perform this check by
  467. // determining whether the DDSCAPS_ZBUFFER flag is set in lpDDSurfaceDesc
  468. // ddsCaps.dwCaps.
  469. //
  470. // Parameters
  471. //
  472. // pccsd
  473. // Points to the DD_CANCREATESURFACEDATA structure containing the
  474. // information required for the driver to determine whether a surface
  475. // can be created.
  476. //
  477. // .lpDD
  478. // Points to the DD_DIRECTDRAW_GLOBAL structure representing the
  479. // DirectDraw object.
  480. // .lpDDSurfaceDesc
  481. // Points to a DDSURFACEDESC structure that contains a
  482. // description of the surface to be created.
  483. // .bIsDifferentPixelFormat
  484. // Indicates whether the pixel format of the surface to be
  485. // created differs from the primary surface.
  486. // .ddRVal
  487. // Specifies the location in which the driver writes the return
  488. // value of the DdCanCreateSurface callback. A return code of
  489. // DD_OK indicates success.
  490. // .CanCreateSurface
  491. // This is unused on Windows 2000.
  492. //
  493. //-----------------------------------------------------------------------------
  494. DWORD CALLBACK
  495. DdCanCreateSurface(
  496. LPDDHAL_CANCREATESURFACEDATA pccsd )
  497. {
  498. P3_THUNKEDDATA* pThisDisplay;
  499. DBG_CB_ENTRY(DdCanCreateSurface);
  500. GET_THUNKEDDATA(pThisDisplay, pccsd->lpDD);
  501. VALIDATE_MODE_AND_STATE(pThisDisplay);
  502. // ************************* Z BUFFERS *******************************
  503. // We support 15,16,24 and 32 bits Z-buffers
  504. // (wo accounting for stencil bits) on PERMEDIA3
  505. if ((pccsd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) &&
  506. (pccsd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
  507. {
  508. DWORD dwZBitDepth;
  509. // Check out the case of a z buffer with a pixel format
  510. // Complex surfaces aren't allowed to have stencil bits. In
  511. // this case we take the pixel z depth from the old place - the
  512. // surface desc.
  513. if ((pccsd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_COMPLEX) ||
  514. (pccsd->lpDDSurfaceDesc->dwFlags & DDSD_ZBUFFERBITDEPTH) )
  515. {
  516. dwZBitDepth = pccsd->lpDDSurfaceDesc->dwZBufferBitDepth;
  517. }
  518. else
  519. {
  520. // On DX 6 the Z Bit depth is stored in the Pixel Format.
  521. dwZBitDepth =
  522. pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwZBufferBitDepth;
  523. }
  524. // Notice we have to check for a dwZBitDepth of 16 or 32 even if a
  525. // stencil buffer is present. dwZBufferBitDepth in this case will be
  526. // the sum of the z buffer and the stencil buffer bit depth.
  527. if ((dwZBitDepth == 16) || (dwZBitDepth == 32))
  528. {
  529. pccsd->ddRVal = DD_OK;
  530. }
  531. else
  532. {
  533. DISPDBG((WRNLVL,"DdCanCreateSurface ERROR: "
  534. "Depth buffer not 16 or 32 Bits! (%d)",
  535. dwZBitDepth));
  536. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  537. }
  538. DBG_CB_EXIT(DdCanCreateSurface, pccsd->ddRVal);
  539. return DDHAL_DRIVER_HANDLED;
  540. }
  541. // *********************** 3D RENDER TARGETS ***************************
  542. if (pccsd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)
  543. {
  544. // We are going to use this surface as a rendering target
  545. // Notice that this will also cover the case when we're
  546. // trying to create a vidmem texture that will also be used
  547. // as a rendertarget (as we go thorugh this path before
  548. // DDSCAPS_TEXTURE-cap surfaces are processed)
  549. if (!pccsd->bIsDifferentPixelFormat)
  550. {
  551. // we have the same format as the primary . If this is true,
  552. // on DX7 we won't have the ddpfPixelFormat fielded at all.
  553. // But we do support rendertargets and textures of the same
  554. // format as our possible primaries so we return DD_OK
  555. DISPDBG((DBGLVL, "DdCanCreateSurface OK: "
  556. "Same as primary format for "
  557. "rendertarget surface" ));
  558. pccsd->ddRVal = DD_OK;
  559. }
  560. else if( pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB )
  561. {
  562. DDPIXELFORMAT *pPixFmt =
  563. &pccsd->lpDDSurfaceDesc->ddpfPixelFormat;
  564. // Only 32 and 16 (565) RGB modes allowed.
  565. switch (pPixFmt->dwRGBBitCount)
  566. {
  567. case 32:
  568. DISPDBG((DBGLVL, "DdCanCreateSurface OK: "
  569. "32-bit RGB format for "
  570. "rendertarget surface" ));
  571. pccsd->ddRVal = DD_OK;
  572. break;
  573. case 16:
  574. if ((pPixFmt->dwRBitMask == 0xF800) &&
  575. (pPixFmt->dwGBitMask == 0x07E0) &&
  576. (pPixFmt->dwBBitMask == 0x001F))
  577. {
  578. DISPDBG((DBGLVL, "DdCanCreateSurface OK: "
  579. "16-bit 565 RGB format for "
  580. "rendertarget surface" ));
  581. pccsd->ddRVal = DD_OK;
  582. }
  583. else
  584. {
  585. DISPDBG((WRNLVL, "DdCanCreateSurface ERROR: "
  586. "NOT 16-bit 565 RGB format for "
  587. "16BPP rendertarget surface" ));
  588. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  589. }
  590. break;
  591. default:
  592. DISPDBG((WRNLVL, "DdCanCreateSurface ERROR: "
  593. "RGB rendertarget not 16 (565) "
  594. "or 32 bit - wrong pixel format" ));
  595. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  596. break;
  597. }
  598. }
  599. else
  600. {
  601. DISPDBG((WRNLVL, "DdCanCreateSurface ERROR: "
  602. "Rendertarget not an RGB Surface"
  603. " - wrong pixel format" ));
  604. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  605. }
  606. DBG_CB_EXIT(DdCanCreateSurface, pccsd->ddRVal);
  607. return DDHAL_DRIVER_HANDLED;
  608. }
  609. // *************************** TEXTURES **************************
  610. if(pccsd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
  611. {
  612. // Notice that the case when we're trying to create a vidmem
  613. // texture that will also be used as a rendertarget has already
  614. // been taken care of when processing the 3D rendertargets case
  615. // as their valid formats are a subset of the valid texture formats
  616. if (!pccsd->bIsDifferentPixelFormat)
  617. {
  618. // we have the same format as the primary . If this is true,
  619. // on DX7 we won't have the ddpfPixelFormat fielded at all.
  620. // but all primary formats are valid for this driver as
  621. // texture formats as well, so succeed this call
  622. DISPDBG((DBGLVL, "DdCanCreateSurface OK: "
  623. "Same as primary format for "
  624. "texture surface" ));
  625. pccsd->ddRVal = DD_OK;
  626. }
  627. // if the surface is going to be a texture verify it matches one
  628. // of the supported texture formats (already stored in pThisDisplay)
  629. else if (__SUR_bCheckTextureFormat(
  630. pThisDisplay,
  631. &pccsd->lpDDSurfaceDesc->ddpfPixelFormat))
  632. {
  633. // texture surface is in one or our supported texture formats
  634. DISPDBG((DBGLVL, " Texture Surface - OK" ));
  635. pccsd->ddRVal = DD_OK;
  636. }
  637. else
  638. {
  639. // we don't support this kind of texture format
  640. DISPDBG((WRNLVL, "DdCanCreateSurface ERROR: "
  641. "Texture Surface format not supported" ));
  642. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  643. }
  644. DBG_CB_EXIT(DdCanCreateSurface, pccsd->ddRVal);
  645. return DDHAL_DRIVER_HANDLED;
  646. }
  647. // ***********************************************************************
  648. // * OTHER OFFSCREEN SURFACES THAT ARE DIFFERENT FROM THE PRIMARY FORMAT *
  649. // ***********************************************************************
  650. if (pccsd->bIsDifferentPixelFormat)
  651. {
  652. DISPDBG((DBGLVL,"Pixel Format is different to primary"));
  653. if(pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_FOURCC)
  654. {
  655. DISPDBG((DBGLVL, " FourCC requested (%4.4hs, 0x%08lx)",
  656. (LPSTR) &pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC,
  657. pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC ));
  658. switch (pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC)
  659. {
  660. case FOURCC_YUV422:
  661. DISPDBG((WRNLVL,"DdCanCreateSurface OK: "
  662. "Surface requested is YUV422"));
  663. pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwYUVBitCount = 16;
  664. pccsd->ddRVal = DD_OK;
  665. break;
  666. // Disabled for now.
  667. case FOURCC_YUV411:
  668. DISPDBG((WRNLVL,"DdCanCreateSurface ERROR: "
  669. "Surface requested is YUV411 - Disabled"));
  670. pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwYUVBitCount = 32;
  671. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  672. break;
  673. default:
  674. DISPDBG((WRNLVL,"DdCanCreateSurface ERROR: "
  675. "Invalid FOURCC requested, refusing"));
  676. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  677. break;
  678. }
  679. DBG_CB_EXIT(DdCanCreateSurface, pccsd->ddRVal);
  680. return DDHAL_DRIVER_HANDLED;
  681. }
  682. //@@BEGIN_DDKSPLIT
  683. // azn check if the following variations are now still needed
  684. //@@END_DDKSPLIT
  685. // Luminance texture support
  686. else if( (pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags
  687. & DDPF_LUMINANCE) &&
  688. !(pccsd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OVERLAY) )
  689. {
  690. DDPIXELFORMAT *pddpfCur;
  691. // Only 16 and 8-bit modes allowed.
  692. pddpfCur = &(pccsd->lpDDSurfaceDesc->ddpfPixelFormat);
  693. if (pddpfCur->dwLuminanceBitCount == 8)
  694. {
  695. // Check for L8
  696. if (!(pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags &
  697. DDPF_ALPHAPIXELS))
  698. {
  699. DISPDBG((DBGLVL, "DdCanCreateSurface OK: "
  700. " 8 Bit Luminance surface"));
  701. pccsd->ddRVal = DD_OK;
  702. }
  703. // Must be A4:L4
  704. else
  705. {
  706. DISPDBG((DBGLVL, "DdCanCreateSurface OK: "
  707. "4 Bit Luma + 4 Bit Alpha surface"));
  708. pccsd->ddRVal = DD_OK;
  709. }
  710. }
  711. // Check for A8L8
  712. else if (pddpfCur->dwLuminanceBitCount == 16)
  713. {
  714. if (pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags &
  715. DDPF_ALPHAPIXELS)
  716. {
  717. DISPDBG((DBGLVL, "DdCanCreateSurface OK: "
  718. " 16 Bit Luminance + Alpha Surface"));
  719. pccsd->ddRVal = DD_OK;
  720. }
  721. else
  722. {
  723. DISPDBG((WRNLVL, "DdCanCreateSurface ERROR: "
  724. "Bad A8L8 format" ));
  725. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  726. }
  727. }
  728. else
  729. {
  730. DISPDBG((WRNLVL, "DdCanCreateSurface ERROR: "
  731. "Unknown luminance texture" ));
  732. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  733. }
  734. DBG_CB_EXIT(DdCanCreateSurface, pccsd->ddRVal);
  735. return DDHAL_DRIVER_HANDLED;
  736. }
  737. else if( (pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags &
  738. DDPF_ALPHA) &&
  739. !(pccsd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OVERLAY))
  740. {
  741. DDPIXELFORMAT *pddpfCur;
  742. pddpfCur = &(pccsd->lpDDSurfaceDesc->ddpfPixelFormat);
  743. if (pddpfCur->dwAlphaBitDepth == 8)
  744. {
  745. DISPDBG((DBGLVL, "DdCanCreateSurface OK: "
  746. "8 Bit Alpha surface"));
  747. pccsd->ddRVal = DD_OK;
  748. }
  749. else
  750. {
  751. DISPDBG((WRNLVL, "DdCanCreateSurface ERROR: "
  752. "pddpfCur->dwAlphaBitDepth != 8" ));
  753. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  754. }
  755. DBG_CB_EXIT(DdCanCreateSurface, pccsd->ddRVal);
  756. return DDHAL_DRIVER_HANDLED;
  757. }
  758. else if( pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB )
  759. {
  760. DDPIXELFORMAT *pddpfCur;
  761. // Only 32, 16 and 8-bit modes allowed.
  762. pddpfCur = &(pccsd->lpDDSurfaceDesc->ddpfPixelFormat);
  763. switch ( pddpfCur->dwRGBBitCount )
  764. {
  765. case 32:
  766. DISPDBG((DBGLVL, "DdCanCreateSurface OK: "
  767. "RGB 32-bit surface" ));
  768. pccsd->ddRVal = DD_OK;
  769. break;
  770. case 16:
  771. DISPDBG((DBGLVL, "DdCanCreateSurface OK: "
  772. "RGB 16-bit surface" ));
  773. pccsd->ddRVal = DD_OK;
  774. break;
  775. case 8:
  776. DISPDBG((DBGLVL, "DdCanCreateSurface OK: "
  777. "RGB 8-bit Surface" ));
  778. pccsd->ddRVal = DD_OK;
  779. break;
  780. default:
  781. DISPDBG((WRNLVL, "DdCanCreateSurface ERROR: "
  782. "RGB Surface - wrong pixel format" ));
  783. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  784. break;
  785. }
  786. DBG_CB_EXIT(DdCanCreateSurface, pccsd->ddRVal);
  787. return DDHAL_DRIVER_HANDLED;
  788. }
  789. // Since its a different from the primary surface and doesn't fall
  790. // into any of the previous cases, we fail it
  791. DISPDBG((WRNLVL, "DdCanCreateSurface ERROR: "
  792. "Different from the primary surface but unknown" ));
  793. pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT;
  794. DBG_CB_EXIT(DdCanCreateSurface, pccsd->ddRVal);
  795. return DDHAL_DRIVER_HANDLED;
  796. }
  797. // Same format as the primary, we succeed it anyway
  798. DISPDBG((DBGLVL, "DdCanCreateSurface OK: (Def) Same format as primary" ));
  799. pccsd->ddRVal = DD_OK;
  800. DBG_CB_EXIT(DdCanCreateSurface, pccsd->ddRVal);
  801. return DDHAL_DRIVER_HANDLED;
  802. } // DdCanCreateSurface
  803. //-----------------------------Public Routine----------------------------------
  804. //
  805. // DdCreateSurface
  806. //
  807. // Creates a DirectDraw surface.
  808. //
  809. // The driver can allocate the surface memory itself or can request that
  810. // DirectDraw perform the memory management. If the driver performs the
  811. //allocation, it must do the following:
  812. //
  813. // Perform the allocation and write a valid pointer to the memory in the
  814. // fpVidMem member of the DD_SURFACE_GLOBAL structure.
  815. // If the surface has a FourCC format, write the pitch in the lPitch member of
  816. // the DD_SURFACE_GLOBAL and DDSURFACEDESC structures, and update the flags
  817. // accordingly.
  818. //
  819. // Otherwise, the driver can have DirectDraw allocate the surface by returning
  820. // one of the following values in fpVidMem:
  821. //
  822. // DDHAL_PLEASEALLOC_BLOCKSIZE requests that DirectDraw allocate the
  823. // surface memory from offscreen memory.
  824. // DDHAL_PLEASEALLOC_USERMEM requests that DirectDraw allocate the
  825. // surface memory from user memory. The
  826. // driver must also return the size in
  827. // bytes of the memory region in dwUserMemSize.
  828. //
  829. // For DirectDraw to perform the allocation of a surface with a FourCC format,
  830. // the driver must also return the pitch and x- and y-block sizes in lPitch,
  831. // dwBlockSizeX, and dwBlockSizeY, respectively. The pitch must be returned in
  832. // the lPitch member of both the DD_SURFACE_GLOBAL and DDSURFACEDESC structures.
  833. // For linear memory, the driver should set dwBlockSizeX to be the size in bytes
  834. // of the memory region and set dwBlockSizeY to 1.
  835. //
  836. // By default, the driver is not notified when a primary surface is created on
  837. // Windows 2000. However, if the driver supports GUID_NTPrivateDriverCaps and
  838. // the DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION flag is set, then the driver will
  839. // be notified.
  840. //
  841. // Parameters
  842. //
  843. // pcsd
  844. // Points to a DD_CREATESURFACEDATA structure that contains the
  845. // information required to create a surface.
  846. //
  847. // .lpDD
  848. // Points to the DD_DIRECTDRAW_GLOBAL structure representing the
  849. // driver.
  850. // .lpDDSurfaceDesc
  851. // Points to the DDSURFACEDESC structure describing the surface
  852. // that the driver should create.
  853. // .lplpSList
  854. // Points to a list of DD_SURFACE_LOCAL structures describing
  855. // the surface objects created by the driver. On Windows 2000,
  856. // there is usually only one entry in this array. However, if
  857. // the driver supports the Windows 95/98-style surface creation
  858. // techniques using DdGetDriverInfo with GUID_NTPrivateDriverCaps,
  859. // and the driver sets the DDHAL_PRIVATECAP_ATOMICSURFACECREATION
  860. // flag, the member will contain a list of surfaces (usually more
  861. // than one).
  862. // .dwSCnt
  863. // Specifies the number of surfaces in the list to which lplpSList
  864. // points. This value is usually 1 on Windows 2000. However, if
  865. // you support the Windows 95/Windows98-style surface creation
  866. // techniques using DdGetDriverInfo with GUID_NTPrivateDriverCaps,
  867. // the member will contain the actual number of surfaces in the
  868. // list (usually more than one).
  869. // .ddRVal
  870. // Specifies the location in which the driver writes the return
  871. // value of the DdCreateSurface callback. A return code of DD_OK
  872. // indicates success.
  873. // .CreateSurface
  874. // This is unused on Windows 2000.
  875. //
  876. //-----------------------------------------------------------------------------
  877. DWORD CALLBACK
  878. DdCreateSurface(
  879. LPDDHAL_CREATESURFACEDATA pcsd )
  880. {
  881. int i;
  882. DWORD BitDepth;
  883. LPDDRAWI_DDRAWSURFACE_LCL psurf;
  884. LPDDRAWI_DDRAWSURFACE_GBL psurf_gbl;
  885. LPDDRAWI_DDRAWSURFACE_MORE psurf_more;
  886. BOOL bHandled = TRUE;
  887. BOOL bResize = FALSE;
  888. P3_THUNKEDDATA* pThisDisplay;
  889. DWORD dwExtraBytes;
  890. DBG_CB_ENTRY(DdCreateSurface);
  891. GET_THUNKEDDATA(pThisDisplay, pcsd->lpDD);
  892. VALIDATE_MODE_AND_STATE(pThisDisplay);
  893. STOP_SOFTWARE_CURSOR(pThisDisplay);
  894. DDRAW_OPERATION(pContext, pThisDisplay);
  895. for( i=0; i<(int)pcsd->dwSCnt; i++ )
  896. {
  897. DDPIXELFORMAT* pPixFormat = NULL;
  898. psurf = pcsd->lplpSList[i];
  899. psurf_gbl = psurf->lpGbl;
  900. psurf_more = psurf->lpSurfMore;
  901. // Dump debug info about the surface to be created
  902. DISPDBG((DBGLVL, "\nLooking at Surface %d of %d", i + 1, pcsd->dwSCnt));
  903. DISPDBG((DBGLVL,"Surf dimensions: %d x %d", psurf_gbl->wWidth,
  904. psurf_gbl->wHeight ));
  905. DBGDUMP_DDRAWSURFACE_LCL(DBGLVL, psurf);
  906. DISPDBG((DBGLVL, "DdCreateSurface setting NULL"));
  907. psurf_gbl->fpVidMem = 0;
  908. // Get the bitdepth of the surface
  909. BitDepth = DDSurf_BitDepth(psurf);
  910. // All Z buffers need adjusting, and setting the correct bit depth
  911. if (DDSurf_HasPixelFormat(psurf->dwFlags))
  912. {
  913. if (psurf_gbl->ddpfSurface.dwFlags & DDPF_ZBUFFER)
  914. {
  915. DISPDBG((DBGLVL,"Surface is Z Buffer"));
  916. BitDepth = psurf_gbl->ddpfSurface.dwZBufferBitDepth;
  917. // Force the pitch to the correct value - the DX runtime
  918. // sometimes sends us a duff value.
  919. psurf_gbl->lPitch = psurf_gbl->wWidth << ( BitDepth >> 4 );
  920. // Ddraw surfaces in IA64 have to be DWORD aligned in their
  921. // pitch in order for emulation code to work correctly
  922. // And on X86 we declared surfaces will be DWORD aligned in
  923. // DrvGetDirectDrawInfo (vmiData.dwXXXXXAlign = 4)
  924. psurf_gbl->lPitch = MAKE_DWORD_ALIGNED(psurf_gbl->lPitch);
  925. }
  926. }
  927. // Determine if we need to resize the surface to make it fit.
  928. bResize = FALSE;
  929. // The surface is a YUV format surface
  930. if (DDSurf_HasPixelFormat(psurf->dwFlags))
  931. {
  932. if (psurf_gbl->ddpfSurface.dwFlags & DDPF_FOURCC)
  933. {
  934. bResize = TRUE;
  935. switch( psurf_gbl->ddpfSurface.dwFourCC )
  936. {
  937. case FOURCC_YUV422:
  938. DISPDBG((DBGLVL,"Surface is YUV422"));
  939. psurf_gbl->ddpfSurface.dwYUVBitCount = 16;
  940. BitDepth = 16;
  941. break;
  942. case FOURCC_YUV411:
  943. DISPDBG((DBGLVL,"Surface is YUV411"));
  944. psurf_gbl->ddpfSurface.dwYUVBitCount = 32;
  945. BitDepth = 32;
  946. break;
  947. default:
  948. // We should never get here, as CanCreateSurface will
  949. // validate the YUV format for us.
  950. DISPDBG((ERRLVL,"Trying to create an invalid YUV surface!"));
  951. break;
  952. }
  953. }
  954. }
  955. DISPDBG((DBGLVL,"Surface Pitch is: 0x%x", psurf_gbl->lPitch));
  956. // This flag is set if the surface needs resizing.
  957. if (bResize)
  958. {
  959. DWORD dwNewWidth = psurf_gbl->wWidth;
  960. DWORD dwNewHeight = psurf_gbl->wHeight;
  961. DWORD dwHeightAlignment = 1;
  962. DWORD dwWidthAlignment = 1;
  963. DISPDBG((DBGLVL, "Resizing surface"));
  964. while ((dwNewWidth % dwWidthAlignment) != 0) dwNewWidth++;
  965. while ((dwNewHeight % dwHeightAlignment) != 0) dwNewHeight++;
  966. DISPDBG((DBGLVL,"Surface original = %d x %d, Surface new = %d x %d",
  967. psurf_gbl->wWidth, psurf_gbl->wHeight,
  968. dwNewWidth, dwNewHeight));
  969. psurf_gbl->fpVidMem = (FLATPTR) DDHAL_PLEASEALLOC_BLOCKSIZE;
  970. psurf_gbl->lPitch = (DWORD)(dwNewWidth * (BitDepth / 8));
  971. // Ddraw surfaces in IA64 have to be DWORD aligned in their
  972. // pitch in order for emulation code to work correctly
  973. // And on X86 we declared surfaces will be DWORD aligned in
  974. // DrvGetDirectDrawInfo (vmiData.dwXXXXXAlign = 4)
  975. psurf_gbl->lPitch = MAKE_DWORD_ALIGNED(psurf_gbl->lPitch);
  976. psurf_gbl->dwBlockSizeX = (DWORD)((DWORD)dwNewHeight *
  977. (DWORD)psurf_gbl->lPitch );
  978. psurf_gbl->dwBlockSizeY = 1;
  979. }
  980. else
  981. {
  982. psurf_gbl->lPitch = (DWORD)(psurf_gbl->wWidth * (BitDepth / 8));
  983. // Ddraw surfaces in IA64 have to be DWORD aligned in their
  984. // pitch in order for emulation code to work correctly
  985. // And on X86 we declared surfaces will be DWORD aligned in
  986. // DrvGetDirectDrawInfo (vmiData.dwXXXXXAlign = 4)
  987. psurf_gbl->lPitch = MAKE_DWORD_ALIGNED(psurf_gbl->lPitch);
  988. #if DX8_3DTEXTURES
  989. if (psurf_more->ddsCapsEx.dwCaps2 & DDSCAPS2_VOLUME)
  990. {
  991. // Put slice pitch into dwBlockSizeY.
  992. psurf_gbl->dwBlockSizeY = psurf_gbl->lPitch *
  993. psurf_gbl->wHeight;
  994. }
  995. #endif // DX8_3DTEXTURES
  996. }
  997. #if DX7_TEXMANAGEMENT
  998. // If this is going to be a driver managed texture we'll request DX to
  999. // allocate it in a private area in system user memory for us.
  1000. if (psurf_more->ddsCapsEx.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
  1001. {
  1002. pcsd->lpDDSurfaceDesc->lPitch = psurf_gbl->lPitch;
  1003. pcsd->lpDDSurfaceDesc->dwFlags |= DDSD_PITCH;
  1004. if (pcsd->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT)
  1005. {
  1006. pcsd->lpDDSurfaceDesc->lPitch =
  1007. psurf_gbl->lPitch =
  1008. ((pcsd->lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount*
  1009. psurf_gbl->wWidth+31)/32)*4; //make it DWORD aligned
  1010. // Ddraw surfaces in IA64 have to be DWORD aligned in their
  1011. // pitch in order for emulation code to work correctly
  1012. // And on X86 we declared surfaces will be DWORD aligned in
  1013. // DrvGetDirectDrawInfo (vmiData.dwXXXXXAlign = 4)
  1014. pcsd->lpDDSurfaceDesc->lPitch =
  1015. psurf_gbl->lPitch = MAKE_DWORD_ALIGNED(psurf_gbl->lPitch);
  1016. }
  1017. #if WNT_DDRAW
  1018. psurf_gbl->dwUserMemSize = psurf_gbl->lPitch *
  1019. (DWORD)(psurf_gbl->wHeight);
  1020. psurf_gbl->fpVidMem = DDHAL_PLEASEALLOC_USERMEM;
  1021. pcsd->ddRVal = DD_OK;
  1022. DBG_CB_EXIT(DdCreateSurface, pcsd->ddRVal);
  1023. return DDHAL_DRIVER_NOTHANDLED;
  1024. #else
  1025. // Assume all the memory allocation will succeed
  1026. if (i == 0)
  1027. {
  1028. bHandled = TRUE;
  1029. }
  1030. psurf_gbl->fpVidMem = (FLATPTR)HEAP_ALLOC(FL_ZERO_MEMORY,
  1031. psurf_gbl->lPitch*psurf_gbl->wHeight,
  1032. ALLOC_TAG_DX(M));
  1033. if (psurf_gbl->fpVidMem)
  1034. {
  1035. // Move on to the next MIP level, skip calling VRAM allocator
  1036. continue;
  1037. }
  1038. else
  1039. {
  1040. pcsd->ddRVal = DDERR_OUTOFMEMORY;
  1041. DBG_CB_EXIT(DdCreateSurface, pcsd->ddRVal);
  1042. return DDHAL_DRIVER_HANDLED;
  1043. }
  1044. #endif
  1045. }
  1046. #endif // DX7_TEXMANAGEMENT
  1047. // If its not to be created in AGP memory and its not the primary
  1048. // then we allocate the memory using our videomemory allocator
  1049. if ((!(psurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) &&
  1050. (!(psurf->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)))
  1051. {
  1052. P3_MEMREQUEST mmrq;
  1053. DWORD dwResult;
  1054. memset(&mmrq, 0, sizeof(P3_MEMREQUEST));
  1055. mmrq.dwSize = sizeof(P3_MEMREQUEST);
  1056. // Compute what size should be requested for the surface allocation
  1057. #if DX8_3DTEXTURES
  1058. if (psurf_more->ddsCapsEx.dwCaps2 & DDSCAPS2_VOLUME)
  1059. {
  1060. if (bResize)
  1061. {
  1062. DISPDBG((ERRLVL,"No volume with block size alloc"));
  1063. }
  1064. else
  1065. {
  1066. // the depth of volume texture is given in
  1067. // ddsCapsEx.dwCaps4.
  1068. mmrq.dwBytes = (DWORD)psurf_gbl->lPitch *
  1069. (DWORD)psurf_gbl->wHeight *
  1070. (DWORD)psurf_more->ddsCapsEx.dwCaps4;
  1071. }
  1072. }
  1073. else
  1074. #endif // DX8_3DTEXTURES
  1075. {
  1076. if (bResize)
  1077. {
  1078. mmrq.dwBytes = psurf_gbl->dwBlockSizeX *
  1079. psurf_gbl->dwBlockSizeY;
  1080. }
  1081. else
  1082. {
  1083. mmrq.dwBytes = (DWORD)psurf_gbl->lPitch *
  1084. (DWORD)psurf_gbl->wHeight;
  1085. }
  1086. }
  1087. // 16 Byte alignment will work for everything
  1088. mmrq.dwAlign = 16;
  1089. // Figure out where in the video mem to place it
  1090. mmrq.dwFlags = MEM3DL_FIRST_FIT;
  1091. if(__SUR_bSurfPlacement(psurf,
  1092. pcsd->lpDDSurfaceDesc) == MEM3DL_FRONT)
  1093. {
  1094. mmrq.dwFlags |= MEM3DL_FRONT;
  1095. }
  1096. else
  1097. {
  1098. mmrq.dwFlags |= MEM3DL_BACK;
  1099. }
  1100. DISPDBG((DBGLVL,"DdCreateSurface allocating vidmem for handle #%d",
  1101. psurf->lpSurfMore->dwSurfaceHandle));
  1102. // Try allocating it in our video memory
  1103. dwResult = _DX_LIN_AllocateLinearMemory(
  1104. &pThisDisplay->LocalVideoHeap0Info,
  1105. &mmrq);
  1106. // Did we got the memory we asked for?
  1107. if (dwResult != GLDD_SUCCESS)
  1108. {
  1109. // If we have an AGP heap and it is a texture request,
  1110. // don't give up - ask DDRAW to allocate it for us.
  1111. if ((pThisDisplay->bCanAGP) &&
  1112. ((psurf->ddsCaps.dwCaps & DDSCAPS_TEXTURE ) ||
  1113. (psurf->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) ))
  1114. {
  1115. DISPDBG((WRNLVL,"No texture VideoMemory left, "
  1116. "going for AGP"));
  1117. psurf->ddsCaps.dwCaps &= ~DDSCAPS_LOCALVIDMEM;
  1118. psurf->ddsCaps.dwCaps |= DDSCAPS_NONLOCALVIDMEM;
  1119. }
  1120. else
  1121. {
  1122. psurf_gbl->fpVidMem = 0;
  1123. DISPDBG((ERRLVL, "DdCreateSurface: failed, "
  1124. "returning NULL"));
  1125. pcsd->ddRVal = DDERR_OUTOFVIDEOMEMORY;
  1126. START_SOFTWARE_CURSOR(pThisDisplay);
  1127. DBG_CB_EXIT(DdCreateSurface, pcsd->ddRVal);
  1128. return DDHAL_DRIVER_HANDLED;
  1129. }
  1130. }
  1131. else
  1132. {
  1133. // We succeeded. Now update the fpVidMem of the surface
  1134. psurf_gbl->fpVidMem = mmrq.pMem;
  1135. }
  1136. }
  1137. #if WNT_DDRAW
  1138. // NT requires us to set some things up differently
  1139. pcsd->lpDDSurfaceDesc->lPitch = psurf_gbl->lPitch;
  1140. pcsd->lpDDSurfaceDesc->dwFlags |= DDSD_PITCH;
  1141. #endif
  1142. // Mark the surface with the correct video memory type
  1143. if (psurf->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
  1144. {
  1145. DISPDBG((DBGLVL,"Surface is in AGP memory"));
  1146. ASSERTDD(pThisDisplay->bCanAGP,
  1147. "** DdCreateSurface: Somehow managed to create an AGP "
  1148. "texture when AGP disabled" );
  1149. psurf->ddsCaps.dwCaps &= ~DDSCAPS_LOCALVIDMEM;
  1150. psurf->ddsCaps.dwCaps |= DDSCAPS_NONLOCALVIDMEM;
  1151. // let DDraw manage AGP memory (return DDHAL_DRIVER_NOTHANDLED)
  1152. // THIS IS ABSOLUTELY NECESSARY IF WE WANT DDRAW TO ALLOCTE THIS!
  1153. bHandled = FALSE;
  1154. }
  1155. else
  1156. {
  1157. DISPDBG((DBGLVL,"Surface in Local Video Memory"));
  1158. psurf->ddsCaps.dwCaps &= ~DDSCAPS_NONLOCALVIDMEM;
  1159. psurf->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM;
  1160. }
  1161. DISPDBG((DBGLVL, "DdCreateSurface: Surface=0x%08x, vidMem=0x%08x",
  1162. psurf, psurf_gbl->fpVidMem));
  1163. } // for i
  1164. START_SOFTWARE_CURSOR(pThisDisplay);
  1165. //
  1166. // If we allocated the memory successfully then we return OK and
  1167. // say that we handled it. Otherwise we should return DDHAL_DRIVER_NOTHANDLED
  1168. //
  1169. if(bHandled)
  1170. {
  1171. pcsd->ddRVal = DD_OK;
  1172. DBG_CB_EXIT(DdCreateSurface, pcsd->ddRVal);
  1173. return DDHAL_DRIVER_HANDLED;
  1174. }
  1175. else
  1176. {
  1177. // if we return handled, then it is assumed that we did SOMETHING
  1178. // with the surface structures to indicate either what size of block
  1179. // or a new pitch or some modification; or we are returning an error.
  1180. DBG_CB_EXIT(DdCreateSurface, pcsd->ddRVal);
  1181. return DDHAL_DRIVER_NOTHANDLED;
  1182. }
  1183. } // DdCreateSurface
  1184. //-----------------------------Public Routine----------------------------------
  1185. //
  1186. // DdDestroySurface
  1187. //
  1188. // Destroys a DirectDraw surface.
  1189. //
  1190. // If DirectDraw did the memory allocation at surface creation time,
  1191. // DdDestroySurface should return DDHAL_DRIVER_NOTHANDLED.
  1192. //
  1193. // If the driver is performing the surface memory management itself,
  1194. // DdDestroySurface should free the surface memory and perform any other
  1195. // cleanup, such as freeing private data stored in the dwReserved1 members
  1196. // of the DD_SURFACE_GLOBAL and DD_SURFACE_LOCAL structures.
  1197. //
  1198. // Parameters
  1199. //
  1200. // psdd
  1201. // Points to a DD_DESTROYSURFACEDATA structure that contains the
  1202. // information needed to destroy a surface.
  1203. //
  1204. // .lpDD
  1205. // Points to the DD_DIRECTDRAW_GLOBAL structure that describes
  1206. // the driver.
  1207. // .lpDDSurface
  1208. // Points to the DD_SURFACE_LOCAL structure representing the
  1209. // surface object to be destroyed.
  1210. // .ddRVal
  1211. // Specifies the location in which the driver writes the return
  1212. // value of the DdDestroySurface callback. A return code of
  1213. // DD_OK indicates success.
  1214. // .DestroySurface
  1215. // This is unused on Windows 2000.
  1216. //
  1217. //-----------------------------------------------------------------------------
  1218. DWORD CALLBACK
  1219. DdDestroySurface(
  1220. LPDDHAL_DESTROYSURFACEDATA psdd )
  1221. {
  1222. P3_THUNKEDDATA* pThisDisplay;
  1223. DBG_CB_ENTRY(DdDestroySurface);
  1224. GET_THUNKEDDATA(pThisDisplay, psdd->lpDD);
  1225. // make sure the DMA buffer is flushed and
  1226. // complete before we destroy any surface
  1227. STOP_SOFTWARE_CURSOR(pThisDisplay);
  1228. {
  1229. P3_DMA_DEFS();
  1230. DDRAW_OPERATION(pContext, pThisDisplay);
  1231. P3_DMA_GET_BUFFER();
  1232. P3_DMA_FLUSH_BUFFER();
  1233. WAIT_DMA_COMPLETE;
  1234. }
  1235. START_SOFTWARE_CURSOR(pThisDisplay);
  1236. DISPDBG((DBGLVL,"DdDestroySurface handle # %d",
  1237. psdd->lpDDSurface->lpSurfMore->dwSurfaceHandle));
  1238. // If we are destroying a videomemory surface which isn't the primary,
  1239. // we'll need to free ourselves the memory as the driver is managing
  1240. // its own local video memory (though non-local/AGP memory is being
  1241. // managed by DirectDraw)
  1242. if ((!(psdd->lpDDSurface->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)) &&
  1243. (!(psdd->lpDDSurface->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)))
  1244. {
  1245. #if DX7_TEXMANAGEMENT
  1246. // If this is a driver managed texture surface, we need to make sure
  1247. // it is deallocated from video memory before proceeding.
  1248. if (psdd->lpDDSurface->lpSurfMore->ddsCapsEx.dwCaps2 &
  1249. DDSCAPS2_TEXTUREMANAGE)
  1250. {
  1251. if (psdd->lpDDSurface->dwFlags & DDRAWISURF_INVALID)
  1252. {
  1253. // This is not a surface destruction,
  1254. // but a managed surface eviction
  1255. #if W95_DDRAW
  1256. // On Win2k, managed textures are evicted from video memory by
  1257. // _DD_TM_EvictAllManagedTextures() when mode change happens.
  1258. _D3D_TM_RemoveDDSurface(pThisDisplay, psdd->lpDDSurface);
  1259. #endif
  1260. psdd->ddRVal= DD_OK;
  1261. DBG_CB_EXIT(DdDestroySurface, psdd->ddRVal);
  1262. return DDHAL_DRIVER_HANDLED;
  1263. }
  1264. else
  1265. {
  1266. // Normal destruction of managed surface
  1267. _D3D_TM_RemoveDDSurface(pThisDisplay, psdd->lpDDSurface);
  1268. #if W95_DDRAW
  1269. // On Win2k, runtime will free the system memory for drivers.
  1270. if (psdd->lpDDSurface->lpGbl->fpVidMem)
  1271. {
  1272. HEAP_FREE((LPVOID)psdd->lpDDSurface->lpGbl->fpVidMem);
  1273. }
  1274. #endif
  1275. }
  1276. }
  1277. else
  1278. #endif
  1279. {
  1280. // Have no memory to free in error recovery case
  1281. if (psdd->lpDDSurface->lpGbl->fpVidMem)
  1282. {
  1283. _DX_LIN_FreeLinearMemory(&pThisDisplay->LocalVideoHeap0Info,
  1284. (DWORD)(psdd->lpDDSurface->lpGbl->fpVidMem));
  1285. }
  1286. }
  1287. // Must reset the surface pointer to NULL
  1288. DISPDBG((DBGLVL, "DdDestroySurface: setting ptr to NULL"));
  1289. psdd->lpDDSurface->lpGbl->fpVidMem = 0;
  1290. psdd->lpDDSurface->lpGbl->dwReserved1 = 0;
  1291. psdd->ddRVal = DD_OK;
  1292. DBG_CB_EXIT(DdDestroySurface, psdd->ddRVal);
  1293. return DDHAL_DRIVER_HANDLED;
  1294. }
  1295. else
  1296. {
  1297. DISPDBG((WRNLVL, "DdDestroySurface: **NOT** setting ptr to NULL"));
  1298. psdd->lpDDSurface->lpGbl->dwReserved1 = 0;
  1299. psdd->ddRVal = DD_OK;
  1300. DBG_CB_EXIT(DdDestroySurface, psdd->ddRVal);
  1301. return DDHAL_DRIVER_NOTHANDLED;
  1302. }
  1303. } // DdDestroySurface
  1304. //-----------------------------Public Routine----------------------------------
  1305. //
  1306. // DdSetColorKey
  1307. //
  1308. // Sets the color key value for the specified surface.
  1309. //
  1310. // DdSetColorKey sets the source or destination color key for the specified
  1311. // surface. Typically, this callback is implemented only for drivers that
  1312. // support overlays with color key capabilities.
  1313. //
  1314. // Parameters
  1315. //
  1316. // psckd
  1317. // Points to a DD_SETCOLORKEYDATA structure that contains the
  1318. // information required to set the color key for the specified surface.
  1319. //
  1320. // .lpDD
  1321. // Points to the DD_DIRECTDRAW_GLOBAL structure that describes
  1322. // the driver.
  1323. // .lpDDSurface
  1324. // Points to the DD_SURFACE_LOCAL structure that describes the
  1325. // surface with which the color key is to be associated.
  1326. // .dwFlags
  1327. // Specifies which color key is being requested. This member is
  1328. // a bit-wise OR of any of the following values:
  1329. //
  1330. // DDCKEY_COLORSPACE
  1331. // The DDCOLORKEY structure contains a color space. If
  1332. // this bit is not set, the structure contains a single
  1333. // color key.
  1334. // DDCKEY_DESTBLT
  1335. // The DDCOLORKEY structure specifies a color key or color
  1336. // space to be used as a destination color key for blit
  1337. // operations.
  1338. // DDCKEY_DESTOVERLAY
  1339. // The DDCOLORKEY structure specifies a color key or color
  1340. // space to be used as a destination color key for overlay
  1341. // operations.
  1342. // DDCKEY_SRCBLT
  1343. // The DDCOLORKEY structure specifies a color key or color
  1344. // space to be used as a source color key for blit
  1345. // operations.
  1346. // DDCKEY_SRCOVERLAY
  1347. // The DDCOLORKEY structure specifies a color key or color
  1348. // space to be used as a source color key for overlay
  1349. // operations.
  1350. // .ckNew
  1351. // Specifies a DDCOLORKEY structure that specifies the new color
  1352. // key values for the DirectDrawSurface object.
  1353. // .ddRVal
  1354. // Specifies the location in which the driver writes the return
  1355. // value of the DdSetColorKey callback. A return code of DD_OK
  1356. // indicates success.
  1357. // .SetColorKey
  1358. // This is not used on Windows 2000.
  1359. //
  1360. //-----------------------------------------------------------------------------
  1361. DWORD CALLBACK
  1362. DdSetColorKey(
  1363. LPDDHAL_SETCOLORKEYDATA psckd)
  1364. {
  1365. P3_THUNKEDDATA* pThisDisplay;
  1366. DBG_CB_ENTRY(DdSetColorKey);
  1367. GET_THUNKEDDATA(pThisDisplay, psckd->lpDD);
  1368. //@@BEGIN_DDKSPLIT
  1369. #if 0
  1370. // Also, see if this colour key is the one used by the overlay.
  1371. // Yes, we should check that various surfaces agree and so on,
  1372. // but can we assume apps are not going to set these flags if there is
  1373. // no overlay active/appropriate?
  1374. if ( psckd->dwFlags & DDCKEY_DESTOVERLAY )
  1375. {
  1376. pThisDisplay->OverlayDstColourKey = psckd->ckNew.dwColorSpaceLowValue;
  1377. }
  1378. #endif
  1379. //@@END_DDKSPLIT
  1380. // We have to keep track of colorkey changes for D3D videomemory textures
  1381. // associated with (some) D3D context. We don't know however from this call
  1382. // which D3D context this is so we have to do a search through them (if
  1383. // there are any at all)
  1384. if ((DDSCAPS_TEXTURE & psckd->lpDDSurface->ddsCaps.dwCaps) &&
  1385. (DDSCAPS_VIDEOMEMORY & psckd->lpDDSurface->ddsCaps.dwCaps) &&
  1386. (pThisDisplay->pDirectDrawLocalsHashTable != NULL))
  1387. {
  1388. DWORD dwSurfaceHandle = psckd->lpDDSurface->lpSurfMore->dwSurfaceHandle;
  1389. PointerArray* pSurfaceArray;
  1390. // For now we'll assume failure unless proven otherwise
  1391. psckd->ddRVal = DDERR_INVALIDPARAMS;
  1392. // Get a pointer to an array of surface pointers associated to this lpDD
  1393. // The PDD_DIRECTDRAW_LOCAL was stored at D3DCreateSurfaceEx call time
  1394. // in PDD_SURFACE_LOCAL->dwReserved1
  1395. pSurfaceArray = (PointerArray*)
  1396. HT_GetEntry(pThisDisplay->pDirectDrawLocalsHashTable,
  1397. psckd->lpDDSurface->dwReserved1);
  1398. if (pSurfaceArray)
  1399. {
  1400. // Found a surface array associated to this lpDD !
  1401. P3_SURF_INTERNAL* pSurfInternal;
  1402. // Check the surface in this array associated to this surface handle
  1403. pSurfInternal = PA_GetEntry(pSurfaceArray, dwSurfaceHandle);
  1404. if (pSurfInternal)
  1405. {
  1406. // Got it! Now update the color key setting(s)
  1407. pSurfInternal->dwFlagsInt |= DDRAWISURF_HASCKEYSRCBLT;
  1408. pSurfInternal->dwCKLow = psckd->ckNew.dwColorSpaceLowValue;
  1409. pSurfInternal->dwCKHigh = psckd->ckNew.dwColorSpaceHighValue;
  1410. // Report success!
  1411. psckd->ddRVal = DD_OK;
  1412. }
  1413. }
  1414. }
  1415. else
  1416. {
  1417. // No D3D colorkey tracking necessary
  1418. psckd->ddRVal = DD_OK;
  1419. }
  1420. DBG_CB_EXIT(DdSetColorKey, psckd->ddRVal);
  1421. return DDHAL_DRIVER_HANDLED;
  1422. } // DdSetColorKey
  1423. //-----------------------------Public Routine----------------------------------
  1424. //
  1425. // DdGetAvailDriverMemory
  1426. //
  1427. // DdGetAvailDriverMemory queries the amount of free memory in the driver
  1428. // managed memory heap. This function does not need to be implemented if the
  1429. // memory will be managed by DirectDraw.
  1430. //
  1431. // DdGetAvailDriverMemory determines how much free memory is in the driver's
  1432. // private heaps for the specified surface type. The driver should check the
  1433. // surface capabilities specified in DDSCaps against the heaps that it is
  1434. // maintaining internally to determine which heap size to query. For example,
  1435. // if DDSCAPS_NONLOCALVIDMEM is set, the driver should return only
  1436. // contributions from the AGP heaps.
  1437. //
  1438. // The driver indicates its support of DdGetAvailDriverMemory by implementing a
  1439. // response to GUID_MiscellaneousCallbacks in DdGetDriverInfo.
  1440. //
  1441. // Parameters
  1442. //
  1443. // pgadmd
  1444. // Points to a DD_GETAVAILDRIVERMEMORYDATA structure that contains the
  1445. // information required to perform the query.
  1446. //
  1447. // lpDD
  1448. // Points to the DD_DIRECTDRAW_GLOBAL structure that describes
  1449. // the driver.
  1450. // DDSCaps
  1451. // Points to a DDSCAPS structure that describes the type of
  1452. // surface for which memory availability is being queried.
  1453. // The DDSCAPS structure is defined in ddraw.h.
  1454. // dwTotal
  1455. // Specifies the location in which the driver returns the
  1456. // number of bytes of driver-managed memory that can be used
  1457. // for surfaces of the type described by DDSCaps.
  1458. // dwFree
  1459. // Specifies the location in which the driver returns the
  1460. // amount of free memory, in bytes, for the surface type
  1461. // described by DDSCaps.
  1462. // ddRVal
  1463. // Specifies the location in which the driver writes the
  1464. // return value of the DdGetAvailDriverMemory callback. A
  1465. // return code of DD_OK indicates success.
  1466. // GetAvailDriverMemory
  1467. // This is unused on Windows 2000.
  1468. //
  1469. // Return Value
  1470. // DdGetAvailDriverMemory returns one of the following callback codes:
  1471. //
  1472. // DDHAL_DRIVER_HANDLED
  1473. // DDHAL_DRIVER_NOTHANDLED
  1474. //
  1475. // Comments
  1476. //
  1477. // DdGetAvailDriverMemory determines how much free memory is in the
  1478. // driver's private heaps for the specified surface type. The driver
  1479. // should check the surface capabilities specified in DDSCaps against
  1480. // the heaps that it is maintaining internally to determine which heap
  1481. // size to query. For example, if DDSCAPS_NONLOCALVIDMEM is set, the
  1482. // driver should return only contributions from the AGP heaps.
  1483. //
  1484. //-----------------------------------------------------------------------------
  1485. DWORD CALLBACK
  1486. DdGetAvailDriverMemory(
  1487. LPDDHAL_GETAVAILDRIVERMEMORYDATA pgadmd)
  1488. {
  1489. P3_THUNKEDDATA* pThisDisplay;
  1490. DBG_CB_ENTRY(DdGetAvailDriverMemory);
  1491. GET_THUNKEDDATA(pThisDisplay, pgadmd->lpDD);
  1492. VALIDATE_MODE_AND_STATE(pThisDisplay);
  1493. DISPDBG((DBGLVL, "Heap0: dwMemStart:0x%x, dwMemEnd:0x%x",
  1494. pThisDisplay->LocalVideoHeap0Info.dwMemStart,
  1495. pThisDisplay->LocalVideoHeap0Info.dwMemEnd));
  1496. pgadmd->ddRVal = DD_OK;
  1497. if (pgadmd->DDSCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
  1498. {
  1499. DISPDBG((DBGLVL," Not returning AGP heap free memory "
  1500. "(we don't manage it)"));
  1501. DBG_CB_EXIT(DdGetAvailDriverMemory, pgadmd->ddRVal);
  1502. return DDHAL_DRIVER_NOTHANDLED;
  1503. }
  1504. else
  1505. {
  1506. pgadmd->dwTotal = pThisDisplay->LocalVideoHeap0Info.dwMaxChunks *
  1507. pThisDisplay->LocalVideoHeap0Info.dwMemPerChunk;
  1508. pgadmd->dwFree =
  1509. _DX_LIN_GetFreeMemInHeap(&pThisDisplay->LocalVideoHeap0Info);
  1510. }
  1511. DISPDBG((DBGLVL," Returning %d TotalMem, of which %d free",
  1512. pgadmd->dwTotal, pgadmd->dwFree));
  1513. DBG_CB_EXIT(DdGetAvailDriverMemory, pgadmd->ddRVal);
  1514. return DDHAL_DRIVER_HANDLED;
  1515. } // DdGetAvailDriverMemory
  1516. #if W95_DDRAW
  1517. //-----------------------------------------------------------------------------
  1518. //
  1519. // __FindAGPHeap
  1520. //
  1521. //-----------------------------------------------------------------------------
  1522. static void
  1523. __FindAGPHeap(
  1524. P3_THUNKEDDATA* pThisDisplay,
  1525. LPDDRAWI_DIRECTDRAW_GBL lpDD )
  1526. {
  1527. VIDMEMINFO MemInfo = lpDD->vmiData;
  1528. LPVIDMEM pStartHeap;
  1529. LPVIDMEM pCurrentHeap = NULL;
  1530. BOOL bFoundAGPHeap = FALSE;
  1531. if ((pThisDisplay->bCanAGP) &&
  1532. (pThisDisplay->dwGARTDev != 0) &&
  1533. (MemInfo.dwNumHeaps) &&
  1534. (MemInfo.pvmList))
  1535. {
  1536. int i;
  1537. // Look around for a good AGP heap
  1538. pStartHeap = MemInfo.pvmList;
  1539. for (i = 0; i < (int)MemInfo.dwNumHeaps; i++)
  1540. {
  1541. pCurrentHeap = pStartHeap + i;
  1542. if (pCurrentHeap->dwFlags & VIDMEM_ISNONLOCAL)
  1543. {
  1544. bFoundAGPHeap = TRUE;
  1545. break;
  1546. }
  1547. }
  1548. } else {
  1549. DISPDBG((ERRLVL,"Unable to allocate AGP memory (AllocatePrivAGPMem)"));
  1550. }
  1551. if(!bFoundAGPHeap)
  1552. {
  1553. DISPDBG((ERRLVL,"Unable to locate AGP heap (AllocatePrivAGPMem)"));
  1554. }
  1555. pThisDisplay->pAGPHeap = pCurrentHeap;
  1556. } // __FindAGPHeap
  1557. //-----------------------------Public Routine----------------------------------
  1558. // DdUpdateNonLocalHeap
  1559. //
  1560. // Received the address of the AGP Heap and updates the chip.
  1561. //
  1562. //
  1563. //-----------------------------------------------------------------------------
  1564. DWORD CALLBACK
  1565. DdUpdateNonLocalHeap(
  1566. LPDDHAL_UPDATENONLOCALHEAPDATA plhd)
  1567. {
  1568. P3_THUNKEDDATA* pThisDisplay;
  1569. GET_THUNKEDDATA(pThisDisplay, plhd->lpDD);
  1570. DISPDBG((DBGLVL,"** In DdUpdateNonLocalHeap - for Heap 0x%x",
  1571. plhd->dwHeap));
  1572. // Fill in the base pointers
  1573. pThisDisplay->dwGARTDevBase = (DWORD)plhd->fpGARTDev;
  1574. pThisDisplay->dwGARTLinBase = (DWORD)plhd->fpGARTLin;
  1575. // Fill in the changeable base pointers.
  1576. pThisDisplay->dwGARTDev = pThisDisplay->dwGARTDevBase;
  1577. pThisDisplay->dwGARTLin = pThisDisplay->dwGARTLinBase;
  1578. __FindAGPHeap( pThisDisplay, plhd->lpDD );
  1579. DISPDBG((DBGLVL,"GartLin: 0x%x, GartDev: 0x%x",
  1580. plhd->fpGARTLin, plhd->fpGARTDev));
  1581. plhd->ddRVal = DD_OK;
  1582. return DDHAL_DRIVER_HANDLED;
  1583. } // DdUpdateNonLocalHeap()
  1584. //-----------------------------Public Routine----------------------------------
  1585. //
  1586. // DdGetHeapAlignment
  1587. //
  1588. //-----------------------------------------------------------------------------
  1589. DWORD CALLBACK
  1590. DdGetHeapAlignment(
  1591. LPDDHAL_GETHEAPALIGNMENTDATA lpGhaData)
  1592. {
  1593. P3_THUNKEDDATA* pThisDisplay;
  1594. DISPDBG(( DBGLVL,"DdGetHeapAlignment: Heap %d", lpGhaData->dwHeap ));
  1595. if (lpGhaData->dwInstance)
  1596. pThisDisplay = (P3_THUNKEDDATA*)lpGhaData->dwInstance;
  1597. else
  1598. pThisDisplay = (P3_THUNKEDDATA*)g_pDriverData;
  1599. if( lpGhaData->dwHeap <= 2 )
  1600. {
  1601. lpGhaData->Alignment.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
  1602. lpGhaData->Alignment.Texture.Linear.dwStartAlignment = 16;
  1603. lpGhaData->ddRVal = DD_OK;
  1604. return DDHAL_DRIVER_HANDLED;
  1605. }
  1606. else
  1607. {
  1608. lpGhaData->ddRVal = DDERR_INVALIDPARAMS;
  1609. return DDHAL_DRIVER_NOTHANDLED;
  1610. }
  1611. } // DdGetHeapAlignment
  1612. #endif // W95_DDRAW