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.

7086 lines
281 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1994-1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ddgdi32.c
  6. * Content: Contains the cross-process mapping layer similar to gdi32.dll
  7. * on NT that the per-process DLL calls into on Win9X.
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 11-oct-99 smac initial implementation
  12. *
  13. ***************************************************************************/
  14. #include "ddrawpr.h"
  15. #include "dx8priv.h"
  16. #include "d3d8p.h"
  17. #include "d3d8ddi.h"
  18. #include "d3d8sddi.h"
  19. #include "ddithunk.h"
  20. extern HRESULT DDAPI DD_CreateSurface4_Main(LPDIRECTDRAW lpDD,LPDDSURFACEDESC2 lpDDSurfaceDesc,
  21. LPDIRECTDRAWSURFACE FAR *lplpDDSurface,IUnknown FAR *pUnkOuter,BOOL bDoSurfaceDescCheck,
  22. LPDDSURFACEINFO pSysMemInfo, DWORD DX8Flags);
  23. extern void invalidateSurface(LPDDRAWI_DDRAWSURFACE_LCL this_lcl);
  24. extern void makeDEVMODE(LPDDRAWI_DIRECTDRAW_GBL this, LPDDHALMODEINFO pmi, BOOL inexcl, BOOL useRefreshRate, LPDWORD pcds_flags, LPDEVMODE pdm);
  25. void LoseDevice (DDDEVICEHANDLE* pDevice);
  26. DDDEVICEHANDLE* pDeviceList = NULL;
  27. // Bogus value used to initialize write only fields when communicating
  28. // with the driver in debug builds
  29. #define BOGUS_FIELD_VALUE 0xBAADCAFEul
  30. typedef struct _KNOWNENTRY
  31. {
  32. DWORD PCIID;
  33. DWORD VersionMajor; // 0 means all versions
  34. DWORD VersionMinor; // 0 means all versions
  35. DWORD Flags;
  36. } KNOWNENTRY;
  37. const KNOWNENTRY gKnownDeviceList[] =
  38. {
  39. // NVidia
  40. {0x12D20018, 0, 0, KNOWN_ZSTENCILDEPTH}, // Riva 128
  41. {0x10DE0020, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT
  42. {0x10DE0028, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT2
  43. {0x10DE0029, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT2 Ultra
  44. {0x10DE002C, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Vanta
  45. {0x10DE002D, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT2 Model 64
  46. {0x10DE00A0, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Aladdin TNT2
  47. {0x10DE0100, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV10 (GeForce)
  48. {0x10DE0101, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV10 (GeForce DDR)
  49. {0x10DE0103, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV10 (Quadro)
  50. {0x10DE0110, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV11 (GeForce2 MX)
  51. {0x10DE0111, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV11 (GeForce2 MX)
  52. {0x10DE0113, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV11 (Quadro2 MXR)
  53. {0x10DE0150, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV15 (GeForce2)
  54. {0x10DE0151, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV15 (GeForce2 DDR)
  55. {0x10DE0152, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV15 (GeForce2 BR)
  56. {0x10DE0153, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV15 (Quadro2)
  57. {0x10DE0200, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV20 (GeForce 3)
  58. // 3DFX
  59. {0x121A0003, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_R5G6B5}, // Banshee
  60. {0x121A0005, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_R5G6B5}, // Voodoo3
  61. {0x121a0009, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A8R8G8B8}, // Voodoo4/5; same PCI-ID
  62. // ATI
  63. {0x10024742, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  64. {0x10024744, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  65. {0x10024749, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  66. {0x1002474D, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  67. {0x1002474E, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  68. {0x1002474F, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  69. {0x10024750, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  70. {0x10024752, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  71. {0x10024C42, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro (PCI)
  72. {0x10024C49, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro (PCI)
  73. {0x10024C4E, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  74. {0x10024C52, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  75. {0x10024C53, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  76. {0x10024C60, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro LT
  77. {0x10024C4D, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X1R5G5B5}, // Rage Mobility AGP
  78. {0x10024C46, 0x0004000c, 0x00010411, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage Mobility 128
  79. {0x10024C46, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage Mobility 128
  80. {0x10024D46, 0x0004000c, 0x00010411, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage Mobility 128
  81. {0x10024D46, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage Mobility 128
  82. {0x10025046, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS
  83. {0x10025046, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS
  84. {0x10025245, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
  85. {0x10025245, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
  86. {0x10025246, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
  87. {0x10025246, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
  88. {0x1002524B, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 VR PCI //DX8.1
  89. {0x1002524B, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 VR PCI //DX8.1
  90. {0x1002524C, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
  91. {0x1002524C, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
  92. //New 128s for DX8.1:
  93. {0x10025041, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
  94. {0x10025041, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
  95. {0x10025042, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
  96. {0x10025042, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
  97. {0x10025043, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
  98. {0x10025043, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
  99. {0x10025044, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
  100. {0x10025044, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
  101. {0x10025045, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
  102. {0x10025045, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
  103. {0x10025047, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
  104. {0x10025047, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
  105. {0x10025048, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
  106. {0x10025048, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
  107. {0x10025049, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
  108. {0x10025049, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
  109. {0x1002504a, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
  110. {0x1002504a, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
  111. {0x1002504b, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
  112. {0x1002504b, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
  113. {0x1002504c, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
  114. {0x1002504c, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
  115. {0x1002504d, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP DX8.1
  116. {0x1002504d, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP DX8.1
  117. {0x1002504e, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
  118. {0x1002504e, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
  119. {0x1002504f, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
  120. {0x1002504f, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
  121. {0x10025050, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
  122. {0x10025050, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
  123. {0x10025051, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
  124. {0x10025051, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
  125. {0x10025052, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
  126. {0x10025052, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
  127. {0x10025053, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
  128. {0x10025053, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
  129. {0x10025054, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
  130. {0x10025054, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
  131. {0x10025055, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
  132. {0x10025055, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
  133. {0x10025056, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
  134. {0x10025056, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
  135. {0x10025057, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
  136. {0x10025057, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
  137. {0x10025058, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
  138. {0x10025058, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
  139. {0x10025345, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X PCI DX8.1
  140. {0x10025345, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X PCI DX8.1
  141. {0x10025346, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 2X DX8.1
  142. {0x10025346, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 2X DX8.1
  143. {0x10025347, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 4X DX8.1
  144. {0x10025347, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 4X DX8.1
  145. {0x10025348, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X DX8.1
  146. {0x10025348, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X DX8.1
  147. {0x1002534b, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X PCI DX8.1
  148. {0x1002534b, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X PCI DX8.1
  149. {0x1002534c, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 2X DX8.1
  150. {0x1002534c, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 2X DX8.1
  151. {0x1002534d, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 4X DX8.1
  152. {0x1002534d, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 4X DX8.1
  153. {0x1002534e, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X DX8.1
  154. {0x1002534e, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X DX8.1
  155. {0x10025446, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA GL AGP DX8.1
  156. {0x10025446, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA GL AGP DX8.1
  157. {0x1002544c, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA VR AGP DX8.1
  158. {0x1002544c, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA VR AGP DX8.1
  159. {0x10025452, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA4XL VR-R AGP DX8.1
  160. {0x10025452, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA4XL VR-R AGP DX8.1
  161. {0x10025144, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
  162. {0x10025145, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
  163. {0x10025146, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
  164. {0x10025147, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
  165. // Intel
  166. {0x80867800, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Intel i740
  167. {0x80867123, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5}, // Intel 810
  168. {0x80867125, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5}, // Intel 810e
  169. {0x80861132, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5}, // Intel 815
  170. {0x80861A12, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Intel Timna
  171. // Matrox
  172. {0x102b0520, 0x0004000b, 0x000110ea, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G200 PCI
  173. {0x102b0520, 0, 0, KNOWN_ZSTENCILDEPTH}, // G200 PCI
  174. {0x102b0521, 0x0004000b, 0x000110ea, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G200 AGP
  175. {0x102b0521, 0, 0, KNOWN_ZSTENCILDEPTH}, // G200 AGP
  176. {0x102b0525, 0x0004000b, 0x000110ea, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G400, G450
  177. {0x102b0525, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G400, G450
  178. // 3DLabs
  179. {0x3d3d0008, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH}, // 3DLabs Gamma
  180. {0x104c3d07, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8}, // Perm2
  181. {0x3d3d0009, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8}, // Perm2
  182. {0x3d3d000a, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Perm3
  183. {0x3d3d000c, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Perm3
  184. // Videologic
  185. {0x104a0010, 0x0004000c, 0x0001080c, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // PowerVR Kyro updated driver
  186. {0x104a0010, 0, 0, KNOWN_ZSTENCILDEPTH}, // PowerVR Kyro
  187. // S3
  188. {0x53338811, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge
  189. {0x53335631, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge
  190. {0x53338a01, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge DX/GX DX8.1
  191. {0x53338c01, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge MX DX8.1
  192. {0x53338a10, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge GX2 DX8.1
  193. {0x53338a20, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Savage3D
  194. {0x53338a22, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Savage4
  195. {0x53339102, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Savage2K
  196. {0x53338c10, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5}, // Savage MX DX8.1
  197. {0x53338c12, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5}, // Savage IX DX8.1
  198. {0x53338a25, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Savage Pro DX8.1
  199. {0x53338a26, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Savage Pro DX8.1
  200. // Trident
  201. {0x10239880, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Trident Blade 3D 9880
  202. {0x10238500, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Trident Blade 3D/ProMedia DX8.1
  203. {0x10238400, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Trident Blade 3D/MVP4 DX8.1
  204. {0x10238420, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Trident CyberBlade i7
  205. {0x10239910, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Trident CyberBlade DX8.1
  206. // SiS
  207. {0x10390300, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_R5G6B5}, // SiS 300
  208. {0x10390300, 0x0004000d, 0x000107da, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 300
  209. {0x10395300, 0x0004000d, 0x000107da, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 300
  210. {0x10396326, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // SiS 6326
  211. {0x10396300, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5}, // SiS 6300
  212. {0x10396300, 0x0004000d, 0x000107da, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 6300
  213. {0x10390310, 0x0004000d, 0x00010352, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 6300
  214. {0x10390315, 0x0004000d, 0x00010352, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 6300
  215. {0x10390325, 0x0004000c, 0x000107d3, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 6300
  216. {0x10396325, 0x0004000c, 0x000107d3, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 640/740
  217. {0x126f0720, 0, 0, KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A1R5G5B5} //Silicon Motion Lynx3DM
  218. };
  219. #define NUM_KNOWN_DEVICES (sizeof(gKnownDeviceList)/sizeof(KNOWNENTRY))
  220. #define CACHE_GROW_SIZE 30
  221. #define RESPATH_D3D "Software\\Microsoft\\Direct3D"
  222. // Minimum size of DrawPrimitive buffer associated with a context.
  223. #define MIN_PRIM_BUFFER_SIZE (1 << 14)
  224. // Maximum
  225. #define MAX_PRIM_BUFFER_SIZE (1 << 20)
  226. // Default
  227. #define DEF_PRIM_BUFFER_SIZE (1 << 16)
  228. const DWORD dwOrderedFaces[6] = {
  229. DDSCAPS2_CUBEMAP_POSITIVEX,
  230. DDSCAPS2_CUBEMAP_NEGATIVEX,
  231. DDSCAPS2_CUBEMAP_POSITIVEY,
  232. DDSCAPS2_CUBEMAP_NEGATIVEY,
  233. DDSCAPS2_CUBEMAP_POSITIVEZ,
  234. DDSCAPS2_CUBEMAP_NEGATIVEZ
  235. };
  236. __inline LPDDRAWI_DDRAWSURFACE_INT GetHeavyweightSurf(DDSURFACE* pSurf)
  237. {
  238. return (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT) ? MapLightweightSurface(pSurf) : pSurf->Surface.pHeavy;
  239. }
  240. #define DONE_HEAVYWEIGHT_SURF(x) \
  241. if (((PDDSURFACE)(x))->dwFlags & DDSURFACE_LIGHTWEIGHT) \
  242. UnmapLightweightSurface(x)
  243. HRESULT MapLegacyResult(HRESULT in)
  244. {
  245. HRESULT hr;
  246. switch (in)
  247. {
  248. case DD_OK:
  249. hr = S_OK;
  250. break;
  251. case DDERR_OUTOFVIDEOMEMORY:
  252. hr = D3DERR_OUTOFVIDEOMEMORY;
  253. break;
  254. case DDERR_CURRENTLYNOTAVAIL:
  255. case DDERR_UNSUPPORTED:
  256. hr = D3DERR_NOTAVAILABLE;
  257. break;
  258. case DDERR_OUTOFMEMORY:
  259. hr = E_OUTOFMEMORY;
  260. break;
  261. default:
  262. hr = D3DERR_DRIVERINTERNALERROR;
  263. }
  264. return hr;
  265. }
  266. BOOL FormatCompatibleWithDisplayFormat(
  267. PDDDEVICEHANDLE pDD,
  268. D3DFORMAT Format)
  269. {
  270. return (BOOL) (Format == pDD->DisplayFormatWithAlpha);
  271. }
  272. HRESULT LockDibEngine(LPDDRAWI_DIRECTDRAW_GBL pdrv)
  273. {
  274. HRESULT ret;
  275. LPWORD pdflags;
  276. BOOL isbusy;
  277. pdflags = pdrv->lpwPDeviceFlags;
  278. isbusy = 0;
  279. _asm
  280. {
  281. mov eax, pdflags
  282. bts word ptr [eax], BUSY_BIT
  283. adc isbusy,0
  284. }
  285. if (isbusy && (0 == pdrv->dwWin16LockCnt))
  286. {
  287. D3D_WARN(2, "LOCK_DIBENGINE, dibengine is busy");
  288. ret = DDERR_SURFACEBUSY;
  289. } else
  290. ret = DD_OK;
  291. return ret;
  292. }
  293. void UnlockDibEngine(LPDDRAWI_DIRECTDRAW_GBL pdrv)
  294. {
  295. if (0 == pdrv->dwWin16LockCnt)
  296. {
  297. *pdrv->lpwPDeviceFlags &= ~BUSY;
  298. }
  299. }
  300. #define CALL_D3DHAL_TAKEBUSY_NOWIN16(ret, pDevice, func, data) \
  301. { \
  302. if (func) \
  303. { \
  304. ret = LockDibEngine((pDevice)->pDD->lpLcl->lpGbl); \
  305. if (ret != DD_OK) \
  306. { \
  307. ret = DDHAL_DRIVER_HANDLED; \
  308. } \
  309. else \
  310. { \
  311. ret = (*(func))(data); \
  312. UnlockDibEngine((pDevice)->pDD->lpLcl->lpGbl); \
  313. } \
  314. } \
  315. else \
  316. { \
  317. DPF_ERR("No HAL call available"); \
  318. ret = DDHAL_DRIVER_NOTHANDLED; \
  319. } \
  320. }
  321. #define CALL_D3DHAL_TAKEBUSY_TAKEWIN16(ret, pDevice, func, data) \
  322. { \
  323. ENTER_WIN16LOCK(); \
  324. CALL_D3DHAL_TAKEBUSY_NOWIN16(ret, pDevice, func, data); \
  325. LEAVE_WIN16LOCK(); \
  326. }
  327. BOOL CanKnownDriverDoThis(PDDDEVICEHANDLE pDevice, DWORD Flag)
  328. {
  329. BOOL ret = FALSE;
  330. int i;
  331. if (pDevice->ForceFlagsOff & Flag)
  332. {
  333. return FALSE;
  334. }
  335. else if (pDevice->ForceFlagsOn & Flag)
  336. {
  337. return TRUE;
  338. }
  339. // Only drivers in our known good list can support lightweight
  340. // surfaces
  341. if (pDevice->PCIID == 0)
  342. {
  343. DDDEVICEIDENTIFIER2 DI;
  344. if (InternalGetDeviceIdentifier7( (LPDIRECTDRAW) pDevice->pDD, &DI, 0, FALSE) == DD_OK)
  345. {
  346. pDevice->PCIID = (DI.dwVendorId << 16) | DI.dwDeviceId;
  347. pDevice->DriverVersionHigh = DI.liDriverVersion.HighPart;
  348. pDevice->DriverVersionLow = DI.liDriverVersion.LowPart;
  349. }
  350. }
  351. for (i = 0; i < NUM_KNOWN_DEVICES; i++)
  352. {
  353. if ((gKnownDeviceList[i].PCIID == pDevice->PCIID) &&
  354. (gKnownDeviceList[i].Flags & Flag) &&
  355. ((pDevice->DriverVersionHigh > gKnownDeviceList[i].VersionMajor) ||
  356. ((pDevice->DriverVersionHigh == gKnownDeviceList[i].VersionMajor) &&
  357. (pDevice->DriverVersionLow >= gKnownDeviceList[i].VersionMinor))))
  358. {
  359. ret = TRUE;
  360. break;
  361. }
  362. }
  363. return ret;
  364. }
  365. BOOL IsLightweightSurface(PDDDEVICEHANDLE pDevice, DDSURFACEDESC2* pddsd2, D3DFORMAT Format)
  366. {
  367. // Render targets, Z buffers, cursor surfaces, and any part of flip chain
  368. // must remain heavyweight surfaces.
  369. if (pddsd2->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE |
  370. DDSCAPS_3DDEVICE |
  371. DDSCAPS_ZBUFFER |
  372. DDSCAPS_OFFSCREENPLAIN))
  373. {
  374. return FALSE;
  375. }
  376. // All paletized textures must be heavyweight unless it's at least a DX8
  377. // driver. This is because some DX7 drivers don't handle palettes right.
  378. if ((pDevice->DriverLevel < 8) &&
  379. ((Format == D3DFMT_A8P8) || (Format == D3DFMT_P8)))
  380. {
  381. return FALSE;
  382. }
  383. if (pddsd2->ddsCaps.dwCaps2 & DDSCAPS2_VOLUME)
  384. {
  385. return FALSE;
  386. }
  387. // If it's a static VB or IB, then we can let that be lightweight
  388. if ((pDevice->DriverLevel >= 8) &&
  389. (pddsd2->ddsCaps.dwCaps2 & DDSCAPS_EXECUTEBUFFER) &&
  390. (pddsd2->ddsCaps.dwCaps2 & DDSCAPS2_HINTSTATIC))
  391. {
  392. return TRUE;
  393. }
  394. // Unless it's static, the runtime locks vidmem vbs indefinately,
  395. // so if we make them lightweight they will fill up our cache table
  396. // with 1000s of entries. Therefore, we will make them heavyweight.
  397. if ((pddsd2->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER) &&
  398. (pddsd2->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
  399. {
  400. return FALSE;
  401. }
  402. // Dynamic textures will be frequently locked, so it is inefficient
  403. // to make them light weight.
  404. if ((pddsd2->ddsCaps.dwCaps2 & DDSCAPS2_HINTDYNAMIC) &&
  405. (pddsd2->ddsCaps.dwCaps & DDSCAPS_TEXTURE) &&
  406. (pddsd2->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
  407. {
  408. return FALSE;
  409. }
  410. return TRUE;
  411. }
  412. void UpdateSurfaceCache(DDSURFACE* pSurf)
  413. {
  414. LPDDRAWI_DDRAWSURFACE_LCL pLcl = GET_CACHED_LIGHTWEIGHT_INT(pSurf)->lpLcl;
  415. LPDDRAWI_DDRAWSURFACE_GBL_MORE lpGblMore;
  416. // Update those fields in the lightweight structure that the driver may
  417. // have changed
  418. pSurf->Surface.pLight->GblFlags = pLcl->lpGbl->dwGlobalFlags;
  419. pSurf->Surface.pLight->fpGblVidMem = pLcl->lpGbl->fpVidMem;
  420. pSurf->Surface.pLight->GblPitch = pLcl->lpGbl->lPitch;
  421. pSurf->Surface.pLight->GblReserved1 = pLcl->lpGbl->dwReserved1;
  422. pSurf->Surface.pLight->LclFlags = pLcl->dwFlags;
  423. pSurf->Surface.pLight->LclCaps1 = pLcl->ddsCaps.dwCaps;
  424. pSurf->Surface.pLight->LclReserved1 = pLcl->dwReserved1;
  425. lpGblMore = GET_LPDDRAWSURFACE_GBL_MORE (pLcl->lpGbl);
  426. pSurf->Surface.pLight->GblMoreDriverReserved = lpGblMore->dwDriverReserved;
  427. pSurf->Surface.pLight->GblMoreContentsStamp = lpGblMore->dwContentsStamp;
  428. pSurf->Surface.pLight->pGblMoreUnswappedDriverReserved = lpGblMore->lpvUnswappedDriverReserved;
  429. pSurf->Surface.pLight->fpGblMoreAliasOfVidMem = lpGblMore->fpAliasOfVidMem;
  430. pSurf->Surface.pLight->cGblMorePageUnlocks = lpGblMore->cPageUnlocks;
  431. if (pSurf->Surface.pLight->LclCaps1 & DDSCAPS_LOCALVIDMEM)
  432. {
  433. pSurf->Surface.pLight->fpGblMoreAliasedVidMem = lpGblMore->fpAliasedVidMem;
  434. }
  435. else if (pSurf->Surface.pLight->LclCaps1 & DDSCAPS_NONLOCALVIDMEM)
  436. {
  437. pSurf->Surface.pLight->fpGblMorePhysicalVidMem = lpGblMore->fpPhysicalVidMem;
  438. }
  439. }
  440. LPDDRAWI_DDRAWSURFACE_INT MapLightweightSurface(DDSURFACE* pSurf)
  441. {
  442. LPDDRAWI_DDRAWSURFACE_INT pCached = NULL;
  443. PDDDEVICEHANDLE pDevice = pSurf->pDevice;
  444. int i;
  445. LPDDRAWI_DDRAWSURFACE_GBL_MORE* ppGblMore;
  446. DWORD Lowest;
  447. DWORD LowestEntry;
  448. CACHEENTRY* pCachedEntry = NULL;
  449. UINT CacheIndex;
  450. // If the surface is already mapped, this is pretty easy
  451. if (pSurf->Surface.pLight->CachedIndex)
  452. {
  453. DDASSERT(pSurf->Surface.pLight->CachedIndex & INDEX_IN_USE);
  454. pCachedEntry = GET_CACHED_ENTRY(pSurf);
  455. pCachedEntry->pSurface->dwReserved2++; // up the ref count
  456. pCachedEntry->UsageStamp = pDevice->CacheUsageStamp++;
  457. // Protect against wrap around of the usage stamp
  458. if (pDevice->CacheUsageStamp == 0)
  459. {
  460. for (i = 0; i < pDevice->NumCachedSurfaces; i++)
  461. {
  462. pDevice->pCachedSurfaceTable[i].UsageStamp = 0;
  463. }
  464. }
  465. return pCachedEntry->pSurface;
  466. }
  467. // Otherwise, find an available surface to use
  468. do
  469. {
  470. // Look through the list and look for either a surface that isn't being used,
  471. // or one that we can use with the lowest UsageStamp.
  472. Lowest = LowestEntry = (DWORD) -1;
  473. for (i = 0; i < pDevice->NumCachedSurfaces; i++)
  474. {
  475. if (pDevice->pCachedSurfaceTable[i].pSurface->dwReserved1 == (ULONG_PTR) NULL)
  476. {
  477. pCachedEntry = &(pDevice->pCachedSurfaceTable[i]);
  478. CacheIndex = i;
  479. break;
  480. }
  481. else if ((pDevice->pCachedSurfaceTable[i].pSurface->dwReserved2 == 0) &&
  482. (pDevice->pCachedSurfaceTable[i].UsageStamp < Lowest))
  483. {
  484. Lowest = pDevice->pCachedSurfaceTable[i].UsageStamp;
  485. LowestEntry = (DWORD) i;
  486. }
  487. }
  488. if ((pCachedEntry == NULL) && (LowestEntry != (DWORD) -1))
  489. {
  490. // We don't have an empty one, but we found one that we can flush
  491. UpdateSurfaceCache((DDSURFACE*)(pDevice->pCachedSurfaceTable[LowestEntry].pSurface->dwReserved1));
  492. ((DDSURFACE*)(pDevice->pCachedSurfaceTable[LowestEntry].pSurface->dwReserved1))->Surface.pLight->CachedIndex = 0;
  493. pDevice->pCachedSurfaceTable[LowestEntry].pSurface->dwReserved1 = (ULONG_PTR) NULL;
  494. pCachedEntry = &(pDevice->pCachedSurfaceTable[LowestEntry]);
  495. CacheIndex = LowestEntry;
  496. }
  497. if (pCachedEntry == NULL)
  498. {
  499. // If we still can't find one, then we need to grow the table
  500. int NewNum;
  501. CACHEENTRY* pNewTable;
  502. NewNum = pDevice->NumCachedSurfaces + CACHE_GROW_SIZE;
  503. pNewTable = (CACHEENTRY*) MemAlloc(sizeof(CACHEENTRY) * NewNum);
  504. if (pNewTable == NULL)
  505. {
  506. return NULL;
  507. }
  508. for (i = 0; i < pDevice->NumCachedSurfaces; i++)
  509. {
  510. pNewTable[i] = pDevice->pCachedSurfaceTable[i];
  511. }
  512. while (i < NewNum)
  513. {
  514. pNewTable[i].UsageStamp = 0;
  515. pNewTable[i].pSurface = (LPDDRAWI_DDRAWSURFACE_INT)
  516. MemAlloc(sizeof(DDRAWI_DDRAWSURFACE_INT) +
  517. sizeof(DDRAWI_DDRAWSURFACE_LCL) +
  518. sizeof(DDRAWI_DDRAWSURFACE_GBL) +
  519. sizeof(DDRAWI_DDRAWSURFACE_MORE) +
  520. sizeof(DDRAWI_DDRAWSURFACE_GBL_MORE) +
  521. sizeof(LPDDRAWI_DDRAWSURFACE_GBL_MORE));
  522. if (pNewTable[i].pSurface == NULL)
  523. {
  524. break;
  525. }
  526. else
  527. {
  528. i++;
  529. }
  530. }
  531. if (pDevice->pCachedSurfaceTable != NULL)
  532. {
  533. MemFree(pDevice->pCachedSurfaceTable);
  534. }
  535. pDevice->NumCachedSurfaces = i;
  536. pDevice->pCachedSurfaceTable = pNewTable;
  537. }
  538. } while (pCachedEntry == NULL);
  539. pCachedEntry->UsageStamp = pDevice->CacheUsageStamp++;
  540. // Protect against wrap around of the usage stamp
  541. if (pDevice->CacheUsageStamp == 0)
  542. {
  543. for (i = 0; i < pDevice->NumCachedSurfaces; i++)
  544. {
  545. pDevice->pCachedSurfaceTable[i].UsageStamp = 0;
  546. }
  547. }
  548. // We have the memory that we want to use, so now we need to initialze it
  549. pCached = pCachedEntry->pSurface;
  550. memset(pCached, 0, sizeof(DDRAWI_DDRAWSURFACE_INT) +
  551. sizeof(DDRAWI_DDRAWSURFACE_LCL) +
  552. sizeof(DDRAWI_DDRAWSURFACE_GBL) +
  553. sizeof(DDRAWI_DDRAWSURFACE_MORE) +
  554. sizeof(DDRAWI_DDRAWSURFACE_GBL_MORE) +
  555. sizeof(LPDDRAWI_DDRAWSURFACE_GBL_MORE));
  556. pCached->dwReserved1 = (ULONG_PTR) pSurf;
  557. pCached->dwReserved2 = 1; // Init the ref count
  558. pSurf->Surface.pLight->CachedIndex = CacheIndex | INDEX_IN_USE; // So a used entry is never 0
  559. pCached->lpLcl = (LPDDRAWI_DDRAWSURFACE_LCL)
  560. (((BYTE*)pCached) + sizeof(DDRAWI_DDRAWSURFACE_INT));
  561. pCached->lpLcl->lpSurfMore = (LPDDRAWI_DDRAWSURFACE_MORE)
  562. (((BYTE*)pCached) + sizeof(DDRAWI_DDRAWSURFACE_INT) +
  563. sizeof(DDRAWI_DDRAWSURFACE_LCL));
  564. pCached->lpLcl->lpGbl = (LPDDRAWI_DDRAWSURFACE_GBL)
  565. (((BYTE*)pCached) + sizeof(DDRAWI_DDRAWSURFACE_INT) +
  566. sizeof(DDRAWI_DDRAWSURFACE_LCL) +
  567. sizeof(DDRAWI_DDRAWSURFACE_MORE) +
  568. sizeof(LPDDRAWI_DDRAWSURFACE_GBL_MORE));
  569. ppGblMore = (LPDDRAWI_DDRAWSURFACE_GBL_MORE*) ((BYTE*)(pCached->lpLcl->lpGbl) -
  570. sizeof(LPDDRAWI_DDRAWSURFACE_GBL_MORE));
  571. *ppGblMore = (LPDDRAWI_DDRAWSURFACE_GBL_MORE)
  572. (((BYTE*)pCached) + sizeof(DDRAWI_DDRAWSURFACE_INT) +
  573. sizeof(DDRAWI_DDRAWSURFACE_LCL) +
  574. sizeof(DDRAWI_DDRAWSURFACE_MORE) +
  575. sizeof(LPDDRAWI_DDRAWSURFACE_GBL_MORE) +
  576. sizeof(DDRAWI_DDRAWSURFACE_GBL));
  577. // Now fill it in with the meaningful data
  578. pCached->lpLcl->dwFlags = pSurf->Surface.pLight->LclFlags;
  579. pCached->lpLcl->ddsCaps.dwCaps = pSurf->Surface.pLight->LclCaps1;
  580. pCached->lpLcl->dwReserved1 = pSurf->Surface.pLight->LclReserved1;
  581. pCached->lpLcl->dwModeCreatedIn = pSurf->Surface.pLight->LclModeCreatedIn;
  582. pCached->lpLcl->dwBackBufferCount = pSurf->Surface.pLight->LclBackBufferCount;
  583. pCached->lpLcl->dwProcessId = pDevice->PID;
  584. pCached->lpLcl->lpGbl->dwGlobalFlags = pSurf->Surface.pLight->GblFlags;
  585. pCached->lpLcl->lpGbl->lPitch = pSurf->Surface.pLight->GblPitch;
  586. pCached->lpLcl->lpGbl->wWidth = (WORD) pSurf->Surface.pLight->GblWidth;
  587. pCached->lpLcl->lpGbl->wHeight = (WORD) pSurf->Height;
  588. pCached->lpLcl->lpGbl->dwReserved1 = pSurf->Surface.pLight->GblReserved1;
  589. if (pSurf->Surface.pLight->GblFormat != D3DFMT_UNKNOWN)
  590. {
  591. ConvertToOldFormat(&pCached->lpLcl->lpGbl->ddpfSurface,
  592. pSurf->Surface.pLight->GblFormat);
  593. }
  594. pCached->lpLcl->lpGbl->lpVidMemHeap = pSurf->Surface.pLight->pGblVidMemHeap;
  595. pCached->lpLcl->lpGbl->fpVidMem = pSurf->Surface.pLight->fpGblVidMem;
  596. pCached->lpLcl->lpSurfMore->ddsCapsEx.dwCaps2 = pSurf->Surface.pLight->MoreCaps2;
  597. pCached->lpLcl->lpSurfMore->ddsCapsEx.dwCaps3 = pSurf->Surface.pLight->MoreCaps3;
  598. pCached->lpLcl->lpSurfMore->ddsCapsEx.dwCaps4 = pSurf->Surface.pLight->MoreCaps4;
  599. pCached->lpLcl->lpSurfMore->rgjunc = pSurf->Surface.pLight->MoreRgjunc;
  600. pCached->lpLcl->lpSurfMore->dwSurfaceHandle = pSurf->dwCookie;
  601. if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  602. {
  603. pCached->lpLcl->lpSurfMore->lpDD_lcl = pDevice->pSwDD->lpLcl;
  604. pCached->lpLcl->lpSurfMore->lpDD_int = pDevice->pSwDD;
  605. pCached->lpLcl->lpGbl->lpDD = pDevice->pSwDD->lpLcl->lpGbl;
  606. }
  607. else
  608. {
  609. pCached->lpLcl->lpSurfMore->lpDD_lcl = pDevice->pDD->lpLcl;
  610. pCached->lpLcl->lpSurfMore->lpDD_int = pDevice->pDD;
  611. pCached->lpLcl->lpGbl->lpDD = pDevice->pDD->lpLcl->lpGbl;
  612. }
  613. (*ppGblMore)->dwDriverReserved = pSurf->Surface.pLight->GblMoreDriverReserved;
  614. (*ppGblMore)->dwContentsStamp = pSurf->Surface.pLight->GblMoreContentsStamp;
  615. (*ppGblMore)->lpvUnswappedDriverReserved = pSurf->Surface.pLight->pGblMoreUnswappedDriverReserved;
  616. (*ppGblMore)->fpAliasOfVidMem = pSurf->Surface.pLight->fpGblMoreAliasOfVidMem;
  617. (*ppGblMore)->cPageUnlocks = pSurf->Surface.pLight->cGblMorePageUnlocks;
  618. if (pCached->lpLcl->ddsCaps.dwCaps & DDSCAPS_MIPMAP)
  619. {
  620. pCached->lpLcl->lpSurfMore->dwMipMapCount = pSurf->Surface.pLight->MoreMipMapCount;
  621. }
  622. else
  623. {
  624. pCached->lpLcl->lpSurfMore->dwFVF = pSurf->Surface.pLight->MoreFVF;
  625. }
  626. if (pCached->lpLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
  627. {
  628. pCached->lpLcl->lpSurfMore->dwBytesAllocated = pSurf->Surface.pLight->MoreBytesAllocated;
  629. }
  630. else if (pCached->lpLcl->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
  631. {
  632. (*ppGblMore)->fpPhysicalVidMem = pSurf->Surface.pLight->fpGblMorePhysicalVidMem;
  633. }
  634. else if (pCached->lpLcl->ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM)
  635. {
  636. (*ppGblMore)->fpAliasedVidMem = pSurf->Surface.pLight->fpGblMoreAliasedVidMem;
  637. }
  638. pCached->lpVtbl = (LPVOID) &ddSurface7Callbacks;
  639. return pCached;
  640. }
  641. void UnmapLightweightSurface(DDSURFACE* pSurf)
  642. {
  643. DDASSERT(pSurf->Surface.pLight->CachedIndex & INDEX_IN_USE);
  644. DDASSERT(pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT);
  645. DDASSERT(GET_CACHED_ENTRY(pSurf)->pSurface->dwReserved2 > 0);
  646. if (--(GET_CACHED_ENTRY(pSurf)->pSurface->dwReserved2) == 0)
  647. {
  648. // Vertex and command buffers are used by DP2, so we want to optimize
  649. // for them. Even though we are done using the surface, we will keep
  650. // the heavyweight surface around so we can use it again quickly if
  651. // we need to.
  652. if (!(pSurf->Surface.pLight->LclCaps1 & DDSCAPS_EXECUTEBUFFER))
  653. {
  654. UpdateSurfaceCache(pSurf);
  655. GET_CACHED_ENTRY(pSurf)->pSurface->dwReserved1 = (ULONG_PTR) NULL;
  656. pSurf->Surface.pLight->CachedIndex = 0;
  657. }
  658. }
  659. }
  660. void ReleaseDX7SurfaceHandle(HANDLE hDD, DWORD handle)
  661. {
  662. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  663. pDeviceHandle->SurfaceHandleList.dwList[handle].nextentry =
  664. pDeviceHandle->SurfaceHandleList.dwFreeList;
  665. pDeviceHandle->SurfaceHandleList.dwFreeList = handle;
  666. }
  667. DWORD GetDX7SurfaceHandle (HANDLE hDD)
  668. {
  669. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  670. DWORD handle = pDeviceHandle->SurfaceHandleList.dwFreeList;
  671. if (0==handle)
  672. {
  673. // need to grow the dwList
  674. LPDDSURFACELISTENTRY newList;
  675. DWORD newsize;
  676. DWORD index;
  677. if (NULL != pDeviceHandle->SurfaceHandleList.dwList)
  678. {
  679. // old size(current dwFreeList) must not be zero
  680. DDASSERT(0 != pDeviceHandle->SurfaceHandleList.dwList[0].nextentry);
  681. // new dwFreeList is always gonna be the old dwList[0].nextentry
  682. newsize = pDeviceHandle->SurfaceHandleList.dwList[0].nextentry + LISTGROWSIZE;
  683. newList=(LPDDSURFACELISTENTRY)MemAlloc(newsize*sizeof(DDSURFACELISTENTRY));
  684. if (NULL == newList)
  685. {
  686. DPF_ERR("MemAlloc failure in GetSurfaceHandle()");
  687. return 0;
  688. }
  689. pDeviceHandle->SurfaceHandleList.dwFreeList =
  690. pDeviceHandle->SurfaceHandleList.dwList[0].nextentry;
  691. memcpy((LPVOID)newList,(LPVOID)pDeviceHandle->SurfaceHandleList.dwList,
  692. pDeviceHandle->SurfaceHandleList.dwList[0].nextentry*sizeof(DDSURFACELISTENTRY));
  693. MemFree(pDeviceHandle->SurfaceHandleList.dwList);
  694. }
  695. else
  696. {
  697. newsize = LISTGROWSIZE;
  698. newList=(LPDDSURFACELISTENTRY)MemAlloc(newsize*sizeof(DDSURFACELISTENTRY));
  699. if (NULL == newList)
  700. {
  701. DPF_ERR("MemAlloc failure in GetSurfaceHandle()");
  702. return 0;
  703. }
  704. // start from one as we don't want 0 as a valid handle
  705. pDeviceHandle->SurfaceHandleList.dwFreeList = 1;
  706. }
  707. pDeviceHandle->SurfaceHandleList.dwList=newList;
  708. pDeviceHandle->SurfaceHandleList.dwList[0].nextentry=newsize;
  709. for (index = pDeviceHandle->SurfaceHandleList.dwFreeList;
  710. index < newsize - 1;
  711. index++)
  712. {
  713. newList[index].nextentry=index+1;
  714. }
  715. // indicate end of new FreeList
  716. newList[newsize-1].nextentry=0;
  717. // now pop up one and assign it to handle
  718. handle=pDeviceHandle->SurfaceHandleList.dwFreeList;
  719. }
  720. // handle slot is avialable so just remove it from freeList
  721. pDeviceHandle->SurfaceHandleList.dwFreeList =
  722. pDeviceHandle->SurfaceHandleList.dwList[handle].nextentry;
  723. #if DBG
  724. pDeviceHandle->SurfaceHandleList.dwList[handle].nextentry=0xDEADBEEF;
  725. #endif
  726. pDeviceHandle->SurfaceHandleList.dwList[handle].dwFlags=0; //mark it's new
  727. pDeviceHandle->SurfaceHandleList.dwList[handle].lpSurface=NULL;
  728. DDASSERT (handle > 0);
  729. DDASSERT (handle < pDeviceHandle->SurfaceHandleList.dwList[0].nextentry);
  730. return handle;
  731. }
  732. void FreeSurfaceObject (PDDSURFACE pSurf, BOOL bDestroy)
  733. {
  734. if ((pSurf != NULL) &&
  735. !(pSurf->dwFlags & DDSURFACE_DUMMY))
  736. {
  737. if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  738. {
  739. LPDDRAWI_DDRAWSURFACE_INT pHeavy;
  740. if (pSurf->Surface.pLight != NULL)
  741. {
  742. pHeavy = GetHeavyweightSurf(pSurf);
  743. if (pHeavy != NULL)
  744. {
  745. if (pSurf->dwFlags & DDSURFACE_CREATECOMPLETE)
  746. {
  747. SwDDIDestroySurface (pSurf->pDevice, pSurf, pHeavy->lpLcl);
  748. }
  749. else if (pSurf->dwFlags & DDSURFACE_CREATEEX)
  750. {
  751. pHeavy->lpLcl->lpGbl->fpVidMem = 0;
  752. SwDDICreateSurfaceEx (pSurf->pDevice->pSwDD->lpLcl,
  753. pHeavy->lpLcl);
  754. }
  755. // Uncache the lightweight surface
  756. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  757. {
  758. pHeavy->dwReserved1 = (ULONG_PTR) NULL;
  759. pHeavy->dwReserved2 = 0;
  760. }
  761. }
  762. MemFree (pSurf->Surface.pLight);
  763. pSurf->Surface.pLight = NULL;
  764. }
  765. if (pSurf->dwCookie != 0)
  766. {
  767. ReleaseDX7SurfaceHandle(pSurf->pDevice, pSurf->dwCookie);
  768. pSurf->dwCookie = 0;
  769. }
  770. }
  771. else if (pSurf->dwFlags & DDSURFACE_HEAVYWEIGHT)
  772. {
  773. // If we created a texture handle, free it now
  774. if ((pSurf->dwFlags & DDSURFACE_DX6HANDLE) &&
  775. (pSurf->pDevice->pContext != NULL) &&
  776. (pSurf->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy != NULL))
  777. {
  778. D3DHAL_TEXTUREDESTROYDATA data;
  779. DWORD ret;
  780. data.dwhContext = (ULONG_PTR) pSurf->pDevice->pContext->Context;
  781. data.dwHandle = pSurf->dwCookie;
  782. CALL_D3DHAL_TAKEBUSY_TAKEWIN16(ret,
  783. pSurf->pDevice,
  784. pSurf->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy,
  785. &data);
  786. }
  787. pSurf->dwFlags &= ~DDSURFACE_DX6HANDLE;
  788. // Now delete the heavy weight surface
  789. if (bDestroy)
  790. {
  791. if (pSurf->Surface.pHeavy != NULL)
  792. {
  793. if (pSurf->dwFlags & DDSURFACE_ROOT)
  794. {
  795. InternalSurfaceRelease(pSurf->Surface.pHeavy, FALSE, TRUE);
  796. }
  797. }
  798. pSurf->Surface.pHeavy = NULL;
  799. }
  800. else if (pSurf->Surface.pHeavy != NULL)
  801. {
  802. invalidateSurface(pSurf->Surface.pHeavy->lpLcl);
  803. }
  804. }
  805. else if (pSurf->Surface.pLight != NULL)
  806. {
  807. LPDDRAWI_DDRAWSURFACE_INT pHeavy;
  808. pHeavy = MapLightweightSurface(pSurf);
  809. if (pHeavy != NULL)
  810. {
  811. if (bDestroy)
  812. {
  813. pHeavy->dwIntRefCnt = 1;
  814. pHeavy->lpLcl->dwLocalRefCnt = 1;
  815. pHeavy->lpLcl->lpGbl->dwRefCnt = 1;
  816. if (pSurf->dwFlags & DDSURFACE_ROOT)
  817. {
  818. pHeavy->lpLcl->lpSurfMore->pAddrefedThisOwner = (IUnknown*) pSurf->pDevice->pDD;
  819. }
  820. pHeavy->lpLcl->dwFlags &= ~DDRAWISURF_IMPLICITCREATE;
  821. InternalSurfaceRelease(pHeavy, TRUE, TRUE);
  822. pHeavy->dwReserved1 = (ULONG_PTR) NULL;
  823. pHeavy->dwReserved2 = 0;
  824. }
  825. else
  826. {
  827. invalidateSurface(pHeavy->lpLcl);
  828. DONE_HEAVYWEIGHT_SURF(pSurf);
  829. }
  830. }
  831. if (bDestroy)
  832. {
  833. MemFree (pSurf->Surface.pLight);
  834. pSurf->Surface.pLight = NULL;
  835. }
  836. }
  837. }
  838. }
  839. /*****************************Private*Routine******************************\
  840. * DdConvertToOldFormat
  841. *
  842. * History:
  843. * 3-Nov-1999 -by- Scott MacDonald [smac]
  844. * Wrote it.
  845. \**************************************************************************/
  846. void ConvertToOldFormat(LPDDPIXELFORMAT pOldFormat, D3DFORMAT NewFormat)
  847. {
  848. // Zero out the format to avoid missing
  849. // cases where it isn't initialized right
  850. ZeroMemory(pOldFormat, sizeof(*pOldFormat));
  851. // Set Size
  852. pOldFormat->dwSize = sizeof(DDPIXELFORMAT);
  853. // Convert away
  854. if (HIWORD((DWORD)NewFormat))
  855. {
  856. pOldFormat->dwFlags = DDPF_FOURCC;
  857. pOldFormat->dwFourCC = (DWORD)NewFormat;
  858. return;
  859. }
  860. switch (NewFormat)
  861. {
  862. case D3DFMT_R8G8B8:
  863. pOldFormat->dwFlags = DDPF_RGB;
  864. pOldFormat->dwRBitMask = 0x00ff0000;
  865. pOldFormat->dwGBitMask = 0x0000ff00;
  866. pOldFormat->dwBBitMask = 0x000000ff;
  867. pOldFormat->dwRGBBitCount = 24;
  868. break;
  869. case D3DFMT_A8R8G8B8:
  870. pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
  871. pOldFormat->dwRGBAlphaBitMask = 0xFF000000;
  872. pOldFormat->dwRBitMask = 0x00ff0000;
  873. pOldFormat->dwGBitMask = 0x0000ff00;
  874. pOldFormat->dwBBitMask = 0x000000ff;
  875. pOldFormat->dwRGBBitCount = 32;
  876. break;
  877. case D3DFMT_X8R8G8B8:
  878. pOldFormat->dwFlags = DDPF_RGB;
  879. pOldFormat->dwRBitMask = 0x00ff0000;
  880. pOldFormat->dwGBitMask = 0x0000ff00;
  881. pOldFormat->dwBBitMask = 0x000000ff;
  882. pOldFormat->dwRGBBitCount = 32;
  883. break;
  884. case D3DFMT_R5G6B5:
  885. pOldFormat->dwFlags = DDPF_RGB;
  886. pOldFormat->dwRBitMask = 0x0000f800;
  887. pOldFormat->dwGBitMask = 0x000007e0;
  888. pOldFormat->dwBBitMask = 0x0000001f;
  889. pOldFormat->dwRGBBitCount = 16;
  890. break;
  891. case D3DFMT_X1R5G5B5:
  892. pOldFormat->dwFlags = DDPF_RGB;
  893. pOldFormat->dwRBitMask = 0x00007c00;
  894. pOldFormat->dwGBitMask = 0x000003e0;
  895. pOldFormat->dwBBitMask = 0x0000001f;
  896. pOldFormat->dwRGBBitCount = 16;
  897. break;
  898. case D3DFMT_A1R5G5B5:
  899. pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
  900. pOldFormat->dwRGBAlphaBitMask = 0x00008000;
  901. pOldFormat->dwRBitMask = 0x00007c00;
  902. pOldFormat->dwGBitMask = 0x000003e0;
  903. pOldFormat->dwBBitMask = 0x0000001f;
  904. pOldFormat->dwRGBBitCount = 16;
  905. break;
  906. case D3DFMT_A4R4G4B4:
  907. pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
  908. pOldFormat->dwRGBAlphaBitMask = 0x0000f000;
  909. pOldFormat->dwRBitMask = 0x00000f00;
  910. pOldFormat->dwGBitMask = 0x000000f0;
  911. pOldFormat->dwBBitMask = 0x0000000f;
  912. pOldFormat->dwRGBBitCount = 16;
  913. break;
  914. case D3DFMT_X4R4G4B4:
  915. pOldFormat->dwFlags = DDPF_RGB;
  916. pOldFormat->dwRBitMask = 0x00000f00;
  917. pOldFormat->dwGBitMask = 0x000000f0;
  918. pOldFormat->dwBBitMask = 0x0000000f;
  919. pOldFormat->dwRGBBitCount = 16;
  920. break;
  921. case D3DFMT_R3G3B2:
  922. pOldFormat->dwFlags = DDPF_RGB;
  923. pOldFormat->dwRBitMask = 0x000000e0;
  924. pOldFormat->dwGBitMask = 0x0000001c;
  925. pOldFormat->dwBBitMask = 0x00000003;
  926. pOldFormat->dwRGBBitCount = 8;
  927. break;
  928. case D3DFMT_A8R3G3B2:
  929. pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
  930. pOldFormat->dwRGBAlphaBitMask = 0x0000FF00;
  931. pOldFormat->dwRBitMask = 0x000000e0;
  932. pOldFormat->dwGBitMask = 0x0000001c;
  933. pOldFormat->dwBBitMask = 0x00000003;
  934. pOldFormat->dwRGBBitCount = 16;
  935. break;
  936. case D3DFMT_A8P8:
  937. pOldFormat->dwFlags = DDPF_RGB |
  938. DDPF_ALPHAPIXELS |
  939. DDPF_PALETTEINDEXED8;
  940. pOldFormat->dwRGBAlphaBitMask = 0x0000FF00;
  941. pOldFormat->dwRGBBitCount = 16;
  942. break;
  943. case D3DFMT_P8:
  944. pOldFormat->dwFlags = DDPF_RGB |
  945. DDPF_PALETTEINDEXED8;
  946. pOldFormat->dwRGBBitCount = 8;
  947. break;
  948. case D3DFMT_L8:
  949. pOldFormat->dwFlags = DDPF_LUMINANCE;
  950. pOldFormat->dwLuminanceBitMask = 0x000000FF;
  951. pOldFormat->dwLuminanceBitCount = 8;
  952. break;
  953. case D3DFMT_A8L8:
  954. pOldFormat->dwFlags = DDPF_LUMINANCE |
  955. DDPF_ALPHAPIXELS;
  956. pOldFormat->dwLuminanceAlphaBitMask = 0x0000FF00;
  957. pOldFormat->dwLuminanceBitMask = 0x000000FF;
  958. pOldFormat->dwLuminanceBitCount = 16;
  959. break;
  960. case D3DFMT_A4L4:
  961. pOldFormat->dwFlags = DDPF_LUMINANCE |
  962. DDPF_ALPHAPIXELS;
  963. pOldFormat->dwLuminanceAlphaBitMask = 0x000000F0;
  964. pOldFormat->dwLuminanceBitMask = 0x0000000F;
  965. pOldFormat->dwLuminanceBitCount = 8;
  966. break;
  967. case D3DFMT_V8U8:
  968. pOldFormat->dwFlags = DDPF_BUMPDUDV;
  969. pOldFormat->dwBumpDvBitMask = 0x0000FF00;
  970. pOldFormat->dwBumpDuBitMask = 0x000000FF;
  971. pOldFormat->dwBumpBitCount = 16;
  972. break;
  973. case D3DFMT_L6V5U5:
  974. pOldFormat->dwFlags = DDPF_BUMPDUDV |
  975. DDPF_BUMPLUMINANCE;
  976. pOldFormat->dwBumpLuminanceBitMask = 0x0000FC00;
  977. pOldFormat->dwBumpDvBitMask = 0x000003E0;
  978. pOldFormat->dwBumpDuBitMask = 0x0000001F;
  979. pOldFormat->dwBumpBitCount = 16;
  980. break;
  981. case D3DFMT_X8L8V8U8:
  982. pOldFormat->dwFlags = DDPF_BUMPDUDV |
  983. DDPF_BUMPLUMINANCE;
  984. pOldFormat->dwBumpLuminanceBitMask = 0x00FF0000;
  985. pOldFormat->dwBumpDvBitMask = 0x0000FF00;
  986. pOldFormat->dwBumpDuBitMask = 0x000000FF;
  987. pOldFormat->dwBumpBitCount = 32;
  988. break;
  989. case D3DFMT_A8:
  990. pOldFormat->dwFlags = DDPF_ALPHA;
  991. pOldFormat->dwAlphaBitDepth = 8;
  992. break;
  993. case D3DFMT_D16:
  994. case D3DFMT_D16_LOCKABLE:
  995. pOldFormat->dwFlags = DDPF_ZBUFFER;
  996. pOldFormat->dwZBufferBitDepth = 16;
  997. pOldFormat->dwZBitMask = 0xFFFF;
  998. pOldFormat->dwStencilBitDepth = 0;
  999. pOldFormat->dwStencilBitMask = 0;
  1000. break;
  1001. case D3DFMT_D32:
  1002. pOldFormat->dwFlags = DDPF_ZBUFFER;
  1003. pOldFormat->dwZBufferBitDepth = 32;
  1004. pOldFormat->dwZBitMask = 0xFFFFFFFF;
  1005. pOldFormat->dwStencilBitDepth = 0;
  1006. pOldFormat->dwStencilBitMask = 0;
  1007. break;
  1008. case D3DFMT_D15S1:
  1009. pOldFormat->dwFlags = DDPF_ZBUFFER |
  1010. DDPF_STENCILBUFFER;
  1011. pOldFormat->dwZBufferBitDepth = 16;
  1012. pOldFormat->dwZBitMask = 0xFFFE;
  1013. pOldFormat->dwStencilBitDepth = 1;
  1014. pOldFormat->dwStencilBitMask = 0x0001;
  1015. break;
  1016. case D3DFMT_D24S8:
  1017. pOldFormat->dwFlags = DDPF_ZBUFFER |
  1018. DDPF_STENCILBUFFER;
  1019. pOldFormat->dwZBufferBitDepth = 32;
  1020. pOldFormat->dwZBitMask = 0xFFFFFF00;
  1021. pOldFormat->dwStencilBitDepth = 8;
  1022. pOldFormat->dwStencilBitMask = 0xFF;
  1023. break;
  1024. case D3DFMT_S1D15:
  1025. pOldFormat->dwFlags = DDPF_ZBUFFER |
  1026. DDPF_STENCILBUFFER;;
  1027. pOldFormat->dwZBufferBitDepth = 16;
  1028. pOldFormat->dwZBitMask = 0x7FFF;
  1029. pOldFormat->dwStencilBitDepth = 1;
  1030. pOldFormat->dwStencilBitMask = 0x8000;
  1031. break;
  1032. case D3DFMT_S8D24:
  1033. pOldFormat->dwFlags = DDPF_ZBUFFER |
  1034. DDPF_STENCILBUFFER;;
  1035. pOldFormat->dwZBufferBitDepth = 32;
  1036. pOldFormat->dwZBitMask = 0x00FFFFFF;
  1037. pOldFormat->dwStencilBitDepth = 8;
  1038. pOldFormat->dwStencilBitMask = 0xFF000000;
  1039. break;
  1040. case D3DFMT_X8D24:
  1041. pOldFormat->dwFlags = DDPF_ZBUFFER;
  1042. pOldFormat->dwZBufferBitDepth = 32;
  1043. pOldFormat->dwZBitMask = 0x00FFFFFF;
  1044. pOldFormat->dwStencilBitDepth = 0;
  1045. pOldFormat->dwStencilBitMask = 0x00000000;
  1046. break;
  1047. case D3DFMT_D24X8:
  1048. pOldFormat->dwFlags = DDPF_ZBUFFER;
  1049. pOldFormat->dwZBufferBitDepth = 32;
  1050. pOldFormat->dwZBitMask = 0xFFFFFF00;
  1051. pOldFormat->dwStencilBitDepth = 0;
  1052. pOldFormat->dwStencilBitMask = 0x00000000;
  1053. break;
  1054. case D3DFMT_D24X4S4:
  1055. pOldFormat->dwFlags = DDPF_ZBUFFER |
  1056. DDPF_STENCILBUFFER;
  1057. pOldFormat->dwZBufferBitDepth = 32;
  1058. pOldFormat->dwZBitMask = 0xFFFFFF00;
  1059. pOldFormat->dwStencilBitDepth = 4;
  1060. pOldFormat->dwStencilBitMask = 0x0000000F;
  1061. break;
  1062. case D3DFMT_X4S4D24:
  1063. pOldFormat->dwFlags = DDPF_ZBUFFER |
  1064. DDPF_STENCILBUFFER;
  1065. pOldFormat->dwZBufferBitDepth = 32;
  1066. pOldFormat->dwZBitMask = 0x00FFFFFF;
  1067. pOldFormat->dwStencilBitDepth = 4;
  1068. pOldFormat->dwStencilBitMask = 0x0F000000;
  1069. break;
  1070. default:
  1071. // All other formats are treated as a
  1072. // FOURCC
  1073. pOldFormat->dwFlags = DDPF_FOURCC;
  1074. pOldFormat->dwFourCC = (DWORD)NewFormat;
  1075. break;
  1076. }
  1077. return;
  1078. }
  1079. /*****************************Private*Routine******************************\
  1080. * DdConvertFromOldFormat
  1081. *
  1082. * History:
  1083. * 13-Nov-1999 -by- Scott MacDonald [smac]
  1084. * Wrote it.
  1085. \**************************************************************************/
  1086. void ConvertFromOldFormat(LPDDPIXELFORMAT pOldFormat, D3DFORMAT *pNewFormat)
  1087. {
  1088. *pNewFormat = D3DFMT_UNKNOWN;
  1089. if (pOldFormat->dwFlags & DDPF_FOURCC)
  1090. {
  1091. ((DWORD)*pNewFormat) = pOldFormat->dwFourCC;
  1092. }
  1093. else if (pOldFormat->dwFlags == DDPF_RGB)
  1094. {
  1095. switch (pOldFormat->dwRGBBitCount)
  1096. {
  1097. case 8:
  1098. if ((pOldFormat->dwRBitMask == 0x000000e0) &&
  1099. (pOldFormat->dwGBitMask == 0x0000001c) &&
  1100. (pOldFormat->dwBBitMask == 0x00000003))
  1101. {
  1102. *pNewFormat = D3DFMT_R3G3B2;
  1103. }
  1104. else
  1105. {
  1106. *pNewFormat = D3DFMT_P8;
  1107. }
  1108. break;
  1109. case 16:
  1110. if ((pOldFormat->dwRBitMask == 0x0000f800) &&
  1111. (pOldFormat->dwGBitMask == 0x000007e0) &&
  1112. (pOldFormat->dwBBitMask == 0x0000001f))
  1113. {
  1114. *pNewFormat = D3DFMT_R5G6B5;
  1115. }
  1116. else if ((pOldFormat->dwRBitMask == 0x00007c00) &&
  1117. (pOldFormat->dwGBitMask == 0x000003e0) &&
  1118. (pOldFormat->dwBBitMask == 0x0000001f))
  1119. {
  1120. *pNewFormat = D3DFMT_X1R5G5B5;
  1121. }
  1122. else if ((pOldFormat->dwRBitMask == 0x00000f00) &&
  1123. (pOldFormat->dwGBitMask == 0x000000f0) &&
  1124. (pOldFormat->dwBBitMask == 0x0000000f))
  1125. {
  1126. *pNewFormat = D3DFMT_X4R4G4B4;
  1127. }
  1128. break;
  1129. case 24:
  1130. if ((pOldFormat->dwRBitMask == 0x00ff0000) &&
  1131. (pOldFormat->dwGBitMask == 0x0000ff00) &&
  1132. (pOldFormat->dwBBitMask == 0x000000ff))
  1133. {
  1134. *pNewFormat = D3DFMT_R8G8B8;
  1135. }
  1136. break;
  1137. case 32:
  1138. if ((pOldFormat->dwRBitMask == 0x00ff0000) &&
  1139. (pOldFormat->dwGBitMask == 0x0000ff00) &&
  1140. (pOldFormat->dwBBitMask == 0x000000ff))
  1141. {
  1142. *pNewFormat = D3DFMT_X8R8G8B8;
  1143. }
  1144. break;
  1145. }
  1146. }
  1147. else if (pOldFormat->dwFlags == (DDPF_RGB | DDPF_ALPHAPIXELS))
  1148. {
  1149. switch (pOldFormat->dwRGBBitCount)
  1150. {
  1151. case 16:
  1152. if ((pOldFormat->dwRGBAlphaBitMask == 0x0000FF00) &&
  1153. (pOldFormat->dwRBitMask == 0x000000e0) &&
  1154. (pOldFormat->dwGBitMask == 0x0000001c) &&
  1155. (pOldFormat->dwBBitMask == 0x00000003))
  1156. {
  1157. *pNewFormat = D3DFMT_A8R3G3B2;
  1158. }
  1159. else if ((pOldFormat->dwRGBAlphaBitMask == 0x0000f000) &&
  1160. (pOldFormat->dwRBitMask == 0x00000f00) &&
  1161. (pOldFormat->dwGBitMask == 0x000000f0) &&
  1162. (pOldFormat->dwBBitMask == 0x0000000f))
  1163. {
  1164. *pNewFormat = D3DFMT_A4R4G4B4;
  1165. }
  1166. else if ((pOldFormat->dwRGBAlphaBitMask == 0x0000FF00) &&
  1167. (pOldFormat->dwRBitMask == 0x00000f00) &&
  1168. (pOldFormat->dwGBitMask == 0x000000f0) &&
  1169. (pOldFormat->dwBBitMask == 0x0000000f))
  1170. {
  1171. *pNewFormat = D3DFMT_A4R4G4B4;
  1172. }
  1173. else if ((pOldFormat->dwRGBAlphaBitMask == 0x00008000) &&
  1174. (pOldFormat->dwRBitMask == 0x00007c00) &&
  1175. (pOldFormat->dwGBitMask == 0x000003e0) &&
  1176. (pOldFormat->dwBBitMask == 0x0000001f))
  1177. {
  1178. *pNewFormat = D3DFMT_A1R5G5B5;
  1179. }
  1180. break;
  1181. case 32:
  1182. if ((pOldFormat->dwRGBAlphaBitMask == 0xff000000) &&
  1183. (pOldFormat->dwRBitMask == 0x00ff0000) &&
  1184. (pOldFormat->dwGBitMask == 0x0000ff00) &&
  1185. (pOldFormat->dwBBitMask == 0x000000ff))
  1186. {
  1187. *pNewFormat = D3DFMT_A8R8G8B8;
  1188. }
  1189. break;
  1190. }
  1191. }
  1192. else if (pOldFormat->dwFlags == DDPF_ALPHA)
  1193. {
  1194. if (pOldFormat->dwAlphaBitDepth == 8)
  1195. {
  1196. *pNewFormat = D3DFMT_A8;
  1197. }
  1198. }
  1199. else if (pOldFormat->dwFlags & (DDPF_PALETTEINDEXED8 | DDPF_RGB))
  1200. {
  1201. switch (pOldFormat->dwRGBBitCount)
  1202. {
  1203. case 8:
  1204. if (pOldFormat->dwFlags == (DDPF_PALETTEINDEXED8 | DDPF_RGB))
  1205. {
  1206. *pNewFormat = D3DFMT_P8;
  1207. }
  1208. break;
  1209. case 16:
  1210. if (pOldFormat->dwFlags == (DDPF_PALETTEINDEXED8 |
  1211. DDPF_RGB |
  1212. DDPF_ALPHAPIXELS) &&
  1213. pOldFormat->dwRGBAlphaBitMask == 0xFF00)
  1214. {
  1215. *pNewFormat = D3DFMT_A8P8;
  1216. }
  1217. break;
  1218. }
  1219. }
  1220. else if (pOldFormat->dwFlags == DDPF_ZBUFFER)
  1221. {
  1222. switch (pOldFormat->dwZBufferBitDepth)
  1223. {
  1224. case 32:
  1225. if (pOldFormat->dwZBitMask == 0xffffffff)
  1226. {
  1227. *pNewFormat = D3DFMT_D32;
  1228. }
  1229. else if (pOldFormat->dwZBitMask == 0x00FFFFFF)
  1230. {
  1231. *pNewFormat = D3DFMT_X8D24;
  1232. }
  1233. else if (pOldFormat->dwZBitMask == 0xFFFFFF00)
  1234. {
  1235. *pNewFormat = D3DFMT_D24X8;
  1236. }
  1237. break;
  1238. case 16:
  1239. if (pOldFormat->dwZBitMask == 0xffff)
  1240. {
  1241. *pNewFormat = D3DFMT_D16;
  1242. }
  1243. break;
  1244. }
  1245. }
  1246. else if (pOldFormat->dwFlags == (DDPF_ZBUFFER | DDPF_STENCILBUFFER))
  1247. {
  1248. switch (pOldFormat->dwZBufferBitDepth)
  1249. {
  1250. case 32:
  1251. if ((pOldFormat->dwZBitMask == 0xffffff00) &&
  1252. (pOldFormat->dwStencilBitMask == 0x000000ff) &&
  1253. (pOldFormat->dwStencilBitDepth == 8))
  1254. {
  1255. *pNewFormat = D3DFMT_D24S8;
  1256. }
  1257. else if ((pOldFormat->dwZBitMask == 0x00ffffff) &&
  1258. (pOldFormat->dwStencilBitMask == 0xff000000) &&
  1259. (pOldFormat->dwStencilBitDepth == 8))
  1260. {
  1261. *pNewFormat = D3DFMT_S8D24;
  1262. }
  1263. break;
  1264. case 16:
  1265. if ((pOldFormat->dwZBitMask == 0xfffe) &&
  1266. (pOldFormat->dwStencilBitMask == 0x0001) &&
  1267. (pOldFormat->dwStencilBitDepth == 1))
  1268. {
  1269. *pNewFormat = D3DFMT_D15S1;
  1270. }
  1271. else if ((pOldFormat->dwZBitMask == 0x7fff) &&
  1272. (pOldFormat->dwStencilBitMask == 0x8000) &&
  1273. (pOldFormat->dwStencilBitDepth == 1))
  1274. {
  1275. *pNewFormat = D3DFMT_S1D15;
  1276. }
  1277. break;
  1278. }
  1279. }
  1280. else if (pOldFormat->dwFlags == DDPF_LUMINANCE)
  1281. {
  1282. switch (pOldFormat->dwLuminanceBitCount)
  1283. {
  1284. case 8:
  1285. if (pOldFormat->dwLuminanceBitMask == 0xFF)
  1286. {
  1287. *pNewFormat = D3DFMT_L8;
  1288. }
  1289. break;
  1290. }
  1291. }
  1292. else if (pOldFormat->dwFlags == (DDPF_LUMINANCE | DDPF_ALPHAPIXELS))
  1293. {
  1294. switch (pOldFormat->dwLuminanceBitCount)
  1295. {
  1296. case 8:
  1297. if (pOldFormat->dwLuminanceBitMask == 0x0F &&
  1298. pOldFormat->dwLuminanceAlphaBitMask == 0xF0)
  1299. {
  1300. *pNewFormat = D3DFMT_A4L4;
  1301. }
  1302. case 16:
  1303. if (pOldFormat->dwLuminanceBitMask == 0x00FF &&
  1304. pOldFormat->dwLuminanceAlphaBitMask == 0xFF00)
  1305. {
  1306. *pNewFormat = D3DFMT_A8L8;
  1307. }
  1308. break;
  1309. }
  1310. }
  1311. else if (pOldFormat->dwFlags == DDPF_BUMPDUDV)
  1312. {
  1313. switch (pOldFormat->dwBumpBitCount)
  1314. {
  1315. case 16:
  1316. if (pOldFormat->dwBumpDuBitMask == 0xFF &&
  1317. pOldFormat->dwBumpDvBitMask == 0xFF00)
  1318. {
  1319. *pNewFormat = D3DFMT_V8U8;
  1320. }
  1321. break;
  1322. }
  1323. }
  1324. else if (pOldFormat->dwFlags == (DDPF_BUMPDUDV | DDPF_BUMPLUMINANCE))
  1325. {
  1326. switch (pOldFormat->dwBumpBitCount)
  1327. {
  1328. case 16:
  1329. if (pOldFormat->dwBumpDuBitMask == 0x001F &&
  1330. pOldFormat->dwBumpDvBitMask == 0x03E0 &&
  1331. pOldFormat->dwBumpLuminanceBitMask == 0xFC00)
  1332. {
  1333. *pNewFormat = D3DFMT_L6V5U5;
  1334. }
  1335. break;
  1336. case 32:
  1337. if (pOldFormat->dwBumpDuBitMask == 0x0000FF &&
  1338. pOldFormat->dwBumpDvBitMask == 0x00FF00 &&
  1339. pOldFormat->dwBumpLuminanceBitMask == 0xFF0000)
  1340. {
  1341. *pNewFormat = D3DFMT_X8L8V8U8;
  1342. }
  1343. break;
  1344. }
  1345. }
  1346. }
  1347. // How lost devices work:
  1348. //
  1349. // Device can be lost two ways:
  1350. // 1) A mode change or something occurs, in which DDraw knows about it and
  1351. // calls CleanupD3D8. In this case, we free the surfaces and mark the
  1352. // device as lost.
  1353. //
  1354. // This will only happen when the DDRAW critical section is held, so as long
  1355. // as we check for lost devices while the critical section is held, we are
  1356. // safe to use the surface structures.
  1357. //
  1358. // 2) A DOS box or something occurs in which case we don't know about it,
  1359. // but we can find out by polling the busy bit. This can occur at anytime,
  1360. // although we are gaurenteed that it will never happen while we are holding
  1361. // the win16 lock. In fact, if we don't hold the win16 lock while checking
  1362. // the busy bit, we will get false positives simple by dragging another window
  1363. // around.
  1364. //
  1365. // So, we have to grab the busy bit to check for lost, and we need to hold the
  1366. // DDraw critical section throughout the remained of the call since not holding
  1367. // it can cause surfaces to go away out from under us. Also, when calling HAL
  1368. // we always grab the win16 lock, so in each call we could be grabbing it twice.
  1369. // With all of this in mind, it's probably better just to ENTER_BOTH() before
  1370. // we check for device lost and then LEAVE_BOTH() at the end of the funtion.
  1371. //
  1372. // We can also remove the busybit check from the HAL call since we already know
  1373. // that it's not set since we checked it and are still holding the win16 lock, so
  1374. // nobody else can set.
  1375. void LoseDevice (DDDEVICEHANDLE* pDevice)
  1376. {
  1377. DDSURFACE* pSurf;
  1378. if (!pDevice->bDeviceLost)
  1379. {
  1380. // The device has transitioned to the lost state, so we need
  1381. // walk through the list and free the vidmem surfaces..
  1382. pDevice->bDeviceLost = TRUE;
  1383. pSurf = pDevice->pSurfList;
  1384. while (pSurf != NULL)
  1385. {
  1386. if (IS_SURFACE_LOOSABLE(pSurf))
  1387. {
  1388. FreeSurfaceObject(pSurf, FALSE);
  1389. }
  1390. pSurf = pSurf->pNext;
  1391. }
  1392. }
  1393. }
  1394. BOOL CheckForDeviceLost (HANDLE hDD)
  1395. {
  1396. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  1397. PDDSURFACE pSurf;
  1398. if (pDeviceHandle->bDeviceLost)
  1399. {
  1400. return TRUE;
  1401. }
  1402. // The below check will only be reliable if we are holding the win16 lock.
  1403. // if dwWin16LockCnt != 0 that means BUSY bit was set by DdLock
  1404. if ( 0 == pDeviceHandle->pDD->lpLcl->lpGbl->dwWin16LockCnt &&
  1405. (*(pDeviceHandle->pDD->lpLcl->lpGbl->lpwPDeviceFlags) & BUSY )
  1406. )
  1407. {
  1408. LoseDevice(pDeviceHandle);
  1409. return TRUE;
  1410. }
  1411. return FALSE;
  1412. }
  1413. DWORD WINAPI DdBlt( PD3D8_BLTDATA pBlt )
  1414. {
  1415. DDSURFACE* pSrcSurf = (DDSURFACE*) pBlt->hSrcSurface;
  1416. DDSURFACE* pDstSurf = (DDSURFACE*) pBlt->hDestSurface;
  1417. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pBlt->hDD;
  1418. // Return failure on bad paths
  1419. pBlt->ddRVal = E_FAIL;
  1420. ENTER_BOTH();
  1421. if (CheckForDeviceLost(pBlt->hDD))
  1422. {
  1423. // Some blts should fail, others should succeed:
  1424. // persistant -> non persitant : OK
  1425. // persistant -> persitant : FAIL
  1426. // non persistant -> persistant : FAIL
  1427. // non persistant -> non persistant : OK
  1428. if ((pDstSurf->Pool == D3DPOOL_LOCALVIDMEM) ||
  1429. (pDstSurf->Pool == D3DPOOL_NONLOCALVIDMEM))
  1430. {
  1431. pBlt->ddRVal = DD_OK;
  1432. }
  1433. else
  1434. {
  1435. pBlt->ddRVal = D3DERR_DEVICELOST;
  1436. }
  1437. LEAVE_BOTH();
  1438. return DDHAL_DRIVER_HANDLED;
  1439. }
  1440. #ifdef DEBUG
  1441. // Just a colorfill? Used only in debug for
  1442. // enforcing DISCARD
  1443. if (pSrcSurf == NULL)
  1444. {
  1445. LPDDRAWI_DDRAWSURFACE_INT pHeavyDst;
  1446. pHeavyDst = GetHeavyweightSurf(pDstSurf);
  1447. if (pHeavyDst != NULL)
  1448. {
  1449. pBlt->bltFX.dwSize = sizeof(DDBLTFX);
  1450. pBlt->ddRVal = DD_Surface_Blt((LPDIRECTDRAWSURFACE)pHeavyDst,
  1451. NULL,
  1452. NULL,
  1453. NULL,
  1454. pBlt->dwFlags,
  1455. &pBlt->bltFX);
  1456. if (FAILED(pBlt->ddRVal))
  1457. {
  1458. DPF_ERR("Driver failed color-fill blt");
  1459. }
  1460. DONE_HEAVYWEIGHT_SURF(pDstSurf);
  1461. }
  1462. pBlt->ddRVal = S_OK;
  1463. LEAVE_BOTH();
  1464. return S_OK;
  1465. }
  1466. #endif
  1467. if (DDBLT_COPYVSYNC & pBlt->dwFlags)
  1468. {
  1469. DWORD msCurrentTime;
  1470. DWORD threshold;
  1471. // Compute how many milliseconds there
  1472. // are per refresh. We round down.
  1473. if (pDevice->pDD->lpLcl->lpGbl->dwMonitorFrequency == 0)
  1474. {
  1475. // 60Hz = 16.666ms per frame
  1476. // 75Hz = 13.333ms
  1477. // 85Hz = 11.765ms
  1478. threshold = 13;
  1479. }
  1480. else
  1481. {
  1482. threshold = (DWORD)(1000.0f /
  1483. (float)(pDevice->pDD->lpLcl->lpGbl->dwMonitorFrequency));
  1484. }
  1485. while (1)
  1486. {
  1487. msCurrentTime = GetTickCount();
  1488. // If the previous blt was long
  1489. // enough ago i.e. a refresh, then
  1490. // we can break out this loop
  1491. if ((msCurrentTime - pBlt->msLastPresent) > threshold )
  1492. break;
  1493. }
  1494. // For DDBLT_COPYVSYNC remember the
  1495. // time for this blt was sent
  1496. pBlt->msLastPresent = msCurrentTime;
  1497. }
  1498. if ((pSrcSurf) && (pDstSurf))
  1499. {
  1500. if ((pSrcSurf->Format == pDstSurf->Format ||
  1501. (pBlt->dwFlags & DDBLT_WINDOWCLIP)) &&
  1502. !IS_SOFTWARE_DRIVER_SURFACE(pSrcSurf) &&
  1503. !IS_SOFTWARE_DRIVER_SURFACE(pDstSurf))
  1504. {
  1505. LPDDRAWI_DDRAWSURFACE_INT pHeavySrc;
  1506. LPDDRAWI_DDRAWSURFACE_INT pHeavyDst;
  1507. DWORD dwFlags = pBlt->dwFlags & ~DDBLT_WINDOWCLIP;
  1508. pHeavySrc = GetHeavyweightSurf(pSrcSurf);
  1509. if (pHeavySrc == NULL)
  1510. {
  1511. pBlt->ddRVal = DDERR_OUTOFMEMORY;
  1512. LEAVE_BOTH();
  1513. return DDHAL_DRIVER_HANDLED;
  1514. }
  1515. pHeavyDst = GetHeavyweightSurf(pDstSurf);
  1516. if (pHeavyDst == NULL)
  1517. {
  1518. DONE_HEAVYWEIGHT_SURF(pSrcSurf);
  1519. pBlt->ddRVal = DDERR_OUTOFMEMORY;
  1520. LEAVE_BOTH();
  1521. return DDHAL_DRIVER_HANDLED;
  1522. }
  1523. if ((pBlt->hWnd) && (DDBLT_WINDOWCLIP & pBlt->dwFlags))
  1524. {
  1525. LPDDRAWI_DDRAWCLIPPER_INT pcClipper = pHeavyDst->lpLcl->lpSurfMore->lpDDIClipper;
  1526. DDASSERT(IsWindow(pBlt->hWnd));
  1527. DDASSERT(DDSCAPS_PRIMARYSURFACE & pHeavyDst->lpLcl->ddsCaps.dwCaps);
  1528. DDASSERT(pcClipper);
  1529. if (pcClipper)
  1530. {
  1531. (HWND) pcClipper->lpLcl->lpGbl->hWnd = pBlt->hWnd;
  1532. dwFlags |= DDBLT_WINDOWCLIP;
  1533. DPF(10,"Updated hWnd=%08lx", pBlt->hWnd);
  1534. }
  1535. }
  1536. pBlt->bltFX.dwSize = sizeof(DDBLTFX);
  1537. pBlt->bltFX.dwROP = SRCCOPY;
  1538. pBlt->ddRVal = DD_Surface_Blt((LPDIRECTDRAWSURFACE)pHeavyDst,
  1539. (LPRECT) &(pBlt->rDest),
  1540. (LPDIRECTDRAWSURFACE)pHeavySrc,
  1541. (LPRECT) &(pBlt->rSrc),
  1542. dwFlags,
  1543. &pBlt->bltFX);
  1544. DONE_HEAVYWEIGHT_SURF(pSrcSurf);
  1545. DONE_HEAVYWEIGHT_SURF(pDstSurf);
  1546. }
  1547. if (FAILED(pBlt->ddRVal))
  1548. {
  1549. // !!! Just use GetDC on the DirectDraw surface for now, though this is
  1550. // probably way too slow on drivers which do not support derived
  1551. // surfaces. DirectDraw Blt support should be added soon.
  1552. HDC hDCTarget;
  1553. if ((pBlt->hWnd) && (DDBLT_WINDOWCLIP & pBlt->dwFlags))
  1554. hDCTarget = GetDC(pBlt->hWnd);
  1555. else
  1556. hDCTarget = D3D8GetDC(pBlt->hDestSurface, NULL);
  1557. if (hDCTarget != NULL)
  1558. {
  1559. HDC hDCSource = D3D8GetDC(pBlt->hSrcSurface, NULL);
  1560. if (hDCSource != NULL)
  1561. {
  1562. LONG DestWidth=pBlt->rDest.right - pBlt->rDest.left;
  1563. LONG DestHeight= pBlt->rDest.bottom - pBlt->rDest.top;
  1564. LONG SrcWidth= pBlt->rSrc.right - pBlt->rSrc.left;
  1565. LONG SrcHeight= pBlt->rSrc.bottom - pBlt->rSrc.top;
  1566. if (DestWidth == SrcWidth && DestHeight == SrcHeight)
  1567. {
  1568. if (BitBlt(
  1569. hDCTarget,
  1570. pBlt->rDest.left,
  1571. pBlt->rDest.top,
  1572. DestWidth,
  1573. DestHeight,
  1574. hDCSource,
  1575. pBlt->rSrc.left,
  1576. pBlt->rSrc.top,
  1577. SRCCOPY))
  1578. {
  1579. pBlt->ddRVal = S_OK;
  1580. }
  1581. }
  1582. else
  1583. {
  1584. // COLORONCOLOR is not the default in NT
  1585. int saved = SetStretchBltMode(hDCTarget,COLORONCOLOR);
  1586. if (StretchBlt(
  1587. hDCTarget,
  1588. pBlt->rDest.left,
  1589. pBlt->rDest.top,
  1590. DestWidth,
  1591. DestHeight,
  1592. hDCSource,
  1593. pBlt->rSrc.left,
  1594. pBlt->rSrc.top,
  1595. SrcWidth,
  1596. SrcHeight,
  1597. SRCCOPY))
  1598. {
  1599. pBlt->ddRVal = S_OK;
  1600. }
  1601. // restore to previous mode
  1602. if (saved)
  1603. SetStretchBltMode(hDCTarget,saved);
  1604. }
  1605. D3D8ReleaseDC(pBlt->hSrcSurface, hDCSource);
  1606. }
  1607. if ((pBlt->hWnd) && (DDBLT_WINDOWCLIP & pBlt->dwFlags))
  1608. ReleaseDC(pBlt->hWnd, hDCTarget);
  1609. else
  1610. D3D8ReleaseDC(pBlt->hDestSurface, hDCTarget);
  1611. }
  1612. }
  1613. // We only want to report DP2 errors during the present call because
  1614. // checking for it everywhere is too hard.
  1615. if ((pBlt->ddRVal == DD_OK) &&
  1616. (pDevice->bDP2Error) &&
  1617. (pBlt->dwFlags & DDBLT_WINDOWCLIP))
  1618. {
  1619. pDevice->bDP2Error = FALSE;
  1620. // We use a special error here to mean that the blt succeeded
  1621. // but that that some DP2 failed since the last present
  1622. pBlt->ddRVal = D3DERR_DEFERRED_DP2ERROR;
  1623. }
  1624. LEAVE_BOTH();
  1625. pBlt->ddRVal = MapLegacyResult(pBlt->ddRVal);
  1626. return DDHAL_DRIVER_HANDLED;
  1627. }
  1628. LEAVE_BOTH();
  1629. pBlt->ddRVal = MapLegacyResult(pBlt->ddRVal);
  1630. return DDHAL_DRIVER_NOTHANDLED;
  1631. }
  1632. DWORD APIENTRY DdFlip( PD3D8_FLIPDATA pFlip )
  1633. {
  1634. DDSURFACE* pCurrSurf = (DDSURFACE*) pFlip->hSurfCurr;
  1635. DDSURFACE* pTargSurf = (DDSURFACE*) pFlip->hSurfTarg;
  1636. ENTER_BOTH();
  1637. if (CheckForDeviceLost(pFlip->hDD))
  1638. {
  1639. LEAVE_BOTH();
  1640. pFlip->ddRVal = DD_OK;
  1641. return DDHAL_DRIVER_HANDLED;
  1642. }
  1643. if ((pCurrSurf) && (pCurrSurf->dwFlags & DDSURFACE_HEAVYWEIGHT) &&
  1644. (pTargSurf) && (pTargSurf->dwFlags & DDSURFACE_HEAVYWEIGHT))
  1645. {
  1646. pFlip->ddRVal = MapLegacyResult( DD_Surface_Flip((LPDIRECTDRAWSURFACE)pCurrSurf->Surface.pHeavy,
  1647. (LPDIRECTDRAWSURFACE)pTargSurf->Surface.pHeavy,
  1648. pFlip->dwFlags));
  1649. if (SUCCEEDED(pFlip->ddRVal))
  1650. {
  1651. DDSURFACE Temp;
  1652. // The DirectX runtime swaps the surface handles when it flips, so we
  1653. // need to swap them back to preserve the integrity
  1654. Temp = *pCurrSurf;
  1655. DDASSERT(pCurrSurf->Pitch == pTargSurf->Pitch);
  1656. DDASSERT(pCurrSurf->Pool == pTargSurf->Pool);
  1657. DDASSERT(pCurrSurf->Type == pTargSurf->Type);
  1658. DDASSERT(pCurrSurf->Height == pTargSurf->Height);
  1659. pCurrSurf->dwFlags = pTargSurf->dwFlags;
  1660. pCurrSurf->Surface = pTargSurf->Surface;
  1661. pCurrSurf->fpVidMem = pTargSurf->fpVidMem;
  1662. pCurrSurf->pBits = pTargSurf->pBits;
  1663. pCurrSurf->LockFlags = pTargSurf->LockFlags;
  1664. pCurrSurf->LockRect = pTargSurf->LockRect;
  1665. pTargSurf->dwFlags = Temp.dwFlags;
  1666. pTargSurf->Surface = Temp.Surface;
  1667. pTargSurf->fpVidMem = Temp.fpVidMem;
  1668. pTargSurf->pBits = Temp.pBits;
  1669. pTargSurf->LockFlags = Temp.LockFlags;
  1670. pTargSurf->LockRect = Temp.LockRect;
  1671. // We only want to report DP2 errors during the present call because
  1672. // checking for it everywhere is too hard.
  1673. if (((DDDEVICEHANDLE*)pFlip->hDD)->bDP2Error)
  1674. {
  1675. ((DDDEVICEHANDLE*)pFlip->hDD)->bDP2Error = FALSE;
  1676. // We use a special error here to mean that the flip succeeded
  1677. // but that that some DP2 failed since the last present
  1678. pFlip->ddRVal = D3DERR_DEFERRED_DP2ERROR;
  1679. }
  1680. }
  1681. LEAVE_BOTH();
  1682. return DDHAL_DRIVER_HANDLED;
  1683. }
  1684. LEAVE_BOTH();
  1685. return DDHAL_DRIVER_NOTHANDLED;
  1686. }
  1687. DWORD APIENTRY DdLock( PD3D8_LOCKDATA pLock )
  1688. {
  1689. PDDSURFACE pSurf = (PDDSURFACE) pLock->hSurface;
  1690. HRESULT hr;
  1691. LPDDRAWI_DDRAWSURFACE_INT pHeavyInt;
  1692. // Mask off new flags
  1693. pLock->dwFlags &= (D3DLOCK_READONLY |
  1694. D3DLOCK_DISCARD |
  1695. D3DLOCK_NOOVERWRITE |
  1696. D3DLOCK_NOSYSLOCK);
  1697. // Always turn on Wait
  1698. pLock->dwFlags |= DDLOCK_WAIT;
  1699. if (pSurf->Pool == D3DPOOL_SYSTEMMEM)
  1700. {
  1701. DWORD Width;
  1702. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  1703. {
  1704. pLock->lpSurfData = (LPVOID) pSurf->Surface.pLight->fpGblVidMem;
  1705. pLock->lPitch = pSurf->Surface.pLight->GblPitch;
  1706. Width = pSurf->Surface.pLight->GblWidth;
  1707. }
  1708. else
  1709. {
  1710. ENTER_DDRAW();
  1711. pLock->lpSurfData = (LPVOID) pSurf->Surface.pHeavy->lpLcl->lpGbl->fpVidMem;
  1712. pLock->lPitch = pSurf->Surface.pHeavy->lpLcl->lpGbl->lPitch;
  1713. Width = (DWORD) pSurf->Surface.pHeavy->lpLcl->lpGbl->wWidth;
  1714. LEAVE_DDRAW();
  1715. }
  1716. if (pLock->bHasRange)
  1717. {
  1718. ((BYTE*)pLock->lpSurfData) += pLock->lPitch * pLock->range.Offset;
  1719. }
  1720. else if (pLock->bHasRect)
  1721. {
  1722. ((BYTE*)pLock->lpSurfData) += pLock->lPitch * pLock->rArea.top;
  1723. ((BYTE*)pLock->lpSurfData) += (pLock->lPitch / Width) * pLock->rArea.left;
  1724. }
  1725. hr = DD_OK;
  1726. }
  1727. else if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  1728. {
  1729. ENTER_DDRAW();
  1730. pHeavyInt = GetHeavyweightSurf(pSurf);
  1731. if (pHeavyInt == NULL)
  1732. {
  1733. // This can be caused by an out of memory condition when calling
  1734. // MapLightweightSurface
  1735. hr = DDERR_OUTOFMEMORY;
  1736. }
  1737. else
  1738. {
  1739. if(pLock->bHasRange)
  1740. {
  1741. pLock->bHasRange = FALSE;
  1742. pLock->bHasRect = TRUE;
  1743. pLock->rArea.left = 0;
  1744. pLock->rArea.right = 0;
  1745. pLock->rArea.top = pLock->range.Offset;
  1746. pLock->rArea.bottom = pLock->range.Offset + pLock->range.Size;
  1747. }
  1748. hr = SwDDILock (pLock->hDD, pSurf, pLock, pHeavyInt->lpLcl);
  1749. pLock->lPitch = pHeavyInt->lpLcl->lpGbl->lPitch;
  1750. }
  1751. LEAVE_DDRAW();
  1752. }
  1753. else
  1754. {
  1755. ENTER_BOTH();
  1756. if ((CheckForDeviceLost(pLock->hDD) &&
  1757. pSurf->Pool != D3DPOOL_MANAGED) ||
  1758. (pSurf->dwFlags & DDSURFACE_SYSMEMALLOCATED))
  1759. {
  1760. DWORD Height = pSurf->Height;
  1761. if (Height == 0)
  1762. {
  1763. Height++;
  1764. }
  1765. if ((pSurf->fpVidMem == NULL) ||
  1766. !(pSurf->dwFlags & DDSURFACE_SYSMEMALLOCATED))
  1767. {
  1768. DDASSERT(pSurf->Pool != D3DPOOL_MANAGED);
  1769. if ((pSurf->Type == D3DRTYPE_VOLUME) ||
  1770. (pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
  1771. {
  1772. // For volumes, height actually contains the depth
  1773. pSurf->fpVidMem = (char*) MemAlloc(
  1774. pSurf->iSlicePitch * Height);
  1775. }
  1776. else
  1777. {
  1778. pSurf->fpVidMem = (char*)MemAlloc(pSurf->Pitch * Height);
  1779. }
  1780. if (pSurf->fpVidMem != NULL)
  1781. {
  1782. pSurf->dwFlags |= DDSURFACE_SYSMEMALLOCATED;
  1783. }
  1784. }
  1785. if (pSurf->dwFlags & DDSURFACE_SYSMEMALLOCATED)
  1786. {
  1787. DDASSERT(CheckForDeviceLost(pLock->hDD));
  1788. pLock->lPitch = pSurf->Pitch;
  1789. pLock->lpSurfData = pSurf->fpVidMem;
  1790. pSurf->dwFlags |= DDSURFACE_SYSMEMLOCK;
  1791. if ((pSurf->Type == D3DRTYPE_VOLUME) ||
  1792. (pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
  1793. {
  1794. pLock->lSlicePitch = pSurf->iSlicePitch;
  1795. }
  1796. hr = DD_OK;
  1797. }
  1798. else
  1799. {
  1800. hr = DDERR_GENERIC;
  1801. }
  1802. }
  1803. else
  1804. {
  1805. pHeavyInt = GetHeavyweightSurf(pSurf);
  1806. if (pHeavyInt == NULL)
  1807. {
  1808. // This can be caused by an out of memory condition when calling
  1809. // MapLightweightSurface
  1810. hr = DDERR_OUTOFMEMORY;
  1811. }
  1812. else
  1813. {
  1814. if(pLock->bHasRange)
  1815. {
  1816. pLock->bHasRect = TRUE;
  1817. pSurf->LockRect.left = 0;
  1818. pSurf->LockRect.right = 0;
  1819. pSurf->LockRect.top = pLock->range.Offset;
  1820. pSurf->LockRect.bottom = pLock->range.Offset + pLock->range.Size;
  1821. }
  1822. else
  1823. {
  1824. pSurf->LockRect.left = pLock->rArea.left;
  1825. pSurf->LockRect.right = pLock->rArea.right;
  1826. pSurf->LockRect.top = pLock->rArea.top;
  1827. pSurf->LockRect.bottom = pLock->rArea.bottom;
  1828. }
  1829. if (pLock->bHasBox)
  1830. {
  1831. pLock->bHasRect = TRUE;
  1832. pSurf->LockRect.left = pLock->box.Left;
  1833. pSurf->LockRect.right = pLock->box.Right;
  1834. pSurf->LockRect.top = pLock->box.Top;
  1835. pSurf->LockRect.bottom = pLock->box.Bottom;
  1836. pSurf->LockRect.left |= (pLock->box.Front << 16);
  1837. pSurf->LockRect.right |= (pLock->box.Back << 16);
  1838. }
  1839. hr = InternalLock (pHeavyInt->lpLcl,
  1840. &pLock->lpSurfData,
  1841. pLock->bHasRect ? &pSurf->LockRect : NULL,
  1842. pLock->dwFlags | DDLOCK_NOSYSLOCK | (pSurf->Pool == D3DPOOL_MANAGED ? 0 : DDLOCK_TAKE_WIN16));
  1843. if (hr == DD_OK)
  1844. {
  1845. pLock->lPitch = pHeavyInt->lpLcl->lpGbl->lPitch;
  1846. pSurf->pBits = pLock->lpSurfData;
  1847. pSurf->LockFlags = pLock->dwFlags;
  1848. if (pLock->bHasRect)
  1849. {
  1850. pSurf->dwFlags |= DDSURFACE_LOCKRECT;
  1851. }
  1852. }
  1853. }
  1854. }
  1855. LEAVE_BOTH();
  1856. }
  1857. if ((pSurf->Type == D3DRTYPE_VOLUME) ||
  1858. (pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
  1859. {
  1860. pLock->lSlicePitch = pSurf->iSlicePitch;
  1861. }
  1862. return MapLegacyResult(hr);
  1863. }
  1864. DWORD APIENTRY DdUnlock( PD3D8_UNLOCKDATA pUnlock )
  1865. {
  1866. PDDSURFACE pSurf = (PDDSURFACE) pUnlock->hSurface;
  1867. HRESULT hr = DDERR_GENERIC;
  1868. LPDDRAWI_DDRAWSURFACE_INT pHeavy;
  1869. if (pSurf->Pool == D3DPOOL_SYSTEMMEM)
  1870. {
  1871. hr = DD_OK;
  1872. }
  1873. else
  1874. {
  1875. if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  1876. {
  1877. ENTER_DDRAW();
  1878. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  1879. {
  1880. pHeavy = GET_CACHED_LIGHTWEIGHT_INT(pSurf);
  1881. DDASSERT(pHeavy != NULL);
  1882. }
  1883. else
  1884. {
  1885. pHeavy = pSurf->Surface.pHeavy;
  1886. }
  1887. hr = SwDDIUnlock (pUnlock->hDD, pSurf, pUnlock, pHeavy->lpLcl);
  1888. DONE_HEAVYWEIGHT_SURF(pSurf);
  1889. LEAVE_DDRAW();
  1890. }
  1891. else
  1892. {
  1893. if (pSurf->dwFlags & DDSURFACE_SYSMEMLOCK)
  1894. {
  1895. pSurf->dwFlags &= ~DDSURFACE_SYSMEMLOCK;
  1896. hr = DD_OK;
  1897. }
  1898. else if (pSurf->LockFlags)
  1899. {
  1900. ENTER_BOTH();
  1901. if (CheckForDeviceLost(pUnlock->hDD) && pSurf->Pool != D3DPOOL_MANAGED)
  1902. {
  1903. hr = DD_OK;
  1904. }
  1905. else
  1906. {
  1907. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  1908. {
  1909. pHeavy = GET_CACHED_LIGHTWEIGHT_INT(pSurf);
  1910. DDASSERT(pHeavy != NULL);
  1911. }
  1912. else
  1913. {
  1914. pHeavy = pSurf->Surface.pHeavy;
  1915. }
  1916. hr = InternalUnlock (pHeavy->lpLcl,
  1917. (pSurf->dwFlags & DDSURFACE_LOCKRECT) ? NULL : pSurf->pBits,
  1918. (pSurf->dwFlags & DDSURFACE_LOCKRECT) ? &pSurf->LockRect : NULL,
  1919. pSurf->LockFlags | DDLOCK_NOSYSLOCK | (pSurf->Pool == D3DPOOL_MANAGED ? 0 : DDLOCK_TAKE_WIN16));
  1920. pSurf->LockFlags = 0;
  1921. pSurf->dwFlags &= ~DDSURFACE_LOCKRECT;
  1922. DONE_HEAVYWEIGHT_SURF(pSurf);
  1923. }
  1924. LEAVE_BOTH();
  1925. }
  1926. }
  1927. }
  1928. return MapLegacyResult(hr);
  1929. }
  1930. DWORD APIENTRY DdGetBltStatus( PD3D8_GETBLTSTATUSDATA pGetBltStatus )
  1931. {
  1932. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pGetBltStatus->hDD;
  1933. PDDSURFACE pSurf = (PDDSURFACE) pGetBltStatus->hSurface;
  1934. DDHAL_GETBLTSTATUSDATA gbsd;
  1935. LPDDHALSURFCB_GETBLTSTATUS gbsfn;
  1936. // Software drivers will only do memcpy, so we don't need to call
  1937. // the driver
  1938. pGetBltStatus->ddRVal = DD_OK;
  1939. if (IS_SOFTWARE_DRIVER(pDevice))
  1940. {
  1941. return DDHAL_DRIVER_HANDLED;
  1942. }
  1943. ENTER_BOTH();
  1944. pGetBltStatus->ddRVal = DD_OK;
  1945. if (CheckForDeviceLost(pDevice))
  1946. {
  1947. LEAVE_BOTH();
  1948. return DDHAL_DRIVER_HANDLED;
  1949. }
  1950. /*
  1951. gbsfn = pDevice->pDD->lpLcl->lpDDCB->HALDDMiscellaneous.GetSysmemBltStatus;
  1952. gbsd.GetBltStatus = pDevice->pDD->lpLcl->lpDDCB->HALDDMiscellaneous.GetSysmemBltStatus;
  1953. if( gbsd.GetBltStatus != NULL )
  1954. {
  1955. DWORD rc;
  1956. gbsd.lpDD = pDevice->pDD->lpLcl->lpGbl;
  1957. gbsd.dwFlags = pGetBltStatus->dwFlags;
  1958. gbsd.lpDDSurface = pSurf->Surface.pHeavy->lpLcl;
  1959. DOHALCALL( GetBltStatus, gbsfn, gbsd, rc, FALSE );
  1960. if( rc == DDHAL_DRIVER_HANDLED )
  1961. {
  1962. pGetBltStatus->ddRVal = gbsd.ddRVal;
  1963. }
  1964. }
  1965. */
  1966. LEAVE_BOTH();
  1967. return DDHAL_DRIVER_HANDLED;
  1968. }
  1969. DWORD APIENTRY DdGetFlipStatus( PD3D8_GETFLIPSTATUSDATA pGetFlipStatus )
  1970. {
  1971. DPF_ERR("DdGetFlipStatus");
  1972. return DD_OK;
  1973. }
  1974. DWORD APIENTRY DdSetMode( PD3D8_SETMODEDATA pSetMode )
  1975. {
  1976. UINT BPP;
  1977. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) pSetMode->hDD;
  1978. pSetMode->ddRVal = D3DERR_DRIVERINTERNALERROR;
  1979. switch (pSetMode->Format)
  1980. {
  1981. case D3DFMT_P8:
  1982. BPP = 8;
  1983. break;
  1984. case D3DFMT_R5G6B5:
  1985. case D3DFMT_X1R5G5B5:
  1986. BPP = 16;
  1987. break;
  1988. case D3DFMT_R8G8B8:
  1989. BPP = 24;
  1990. break;
  1991. case D3DFMT_A8R8G8B8:
  1992. case D3DFMT_X8R8G8B8:
  1993. BPP = 32;
  1994. break;
  1995. default:
  1996. return DDHAL_DRIVER_HANDLED;
  1997. }
  1998. pSetMode->ddRVal = D3D8SetMode((HANDLE)pDeviceHandle,
  1999. pDeviceHandle->szDeviceName,
  2000. pSetMode->dwWidth,
  2001. pSetMode->dwHeight,
  2002. BPP,
  2003. pSetMode->dwRefreshRate,
  2004. FALSE);
  2005. return DDHAL_DRIVER_HANDLED;
  2006. }
  2007. DWORD APIENTRY DdDestroyDDLocal( PD3D8_DESTROYDDLOCALDATA pDestroyDDLocal )
  2008. {
  2009. DPF_ERR("DdDestroyDDLocal");
  2010. return DD_OK;
  2011. }
  2012. DWORD APIENTRY DdWaitForVerticalBlank( PD3D8_WAITFORVERTICALBLANKDATA pWaitForVerticalBlank )
  2013. {
  2014. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pWaitForVerticalBlank->hDD;
  2015. LPDDHAL_WAITFORVERTICALBLANK wfvbhalfn;
  2016. LPDDHAL_WAITFORVERTICALBLANK wfvbfn;
  2017. DWORD dwRet = DDHAL_DRIVER_HANDLED;
  2018. ENTER_BOTH();
  2019. if (CheckForDeviceLost(pDevice))
  2020. {
  2021. static int LostTestVerticalBlank;
  2022. pWaitForVerticalBlank->ddRVal = DD_OK;
  2023. if (pWaitForVerticalBlank->dwFlags == DDWAITVB_I_TESTVB)
  2024. {
  2025. if (LostTestVerticalBlank > 0)
  2026. {
  2027. pWaitForVerticalBlank->bIsInVB = TRUE;
  2028. }
  2029. else
  2030. {
  2031. pWaitForVerticalBlank->bIsInVB = FALSE;
  2032. }
  2033. LostTestVerticalBlank = LostTestVerticalBlank == 0 ? 1 : 0;
  2034. }
  2035. else if (pWaitForVerticalBlank->dwFlags == DDWAITVB_BLOCKEND)
  2036. {
  2037. pWaitForVerticalBlank->bIsInVB = FALSE;
  2038. }
  2039. else
  2040. {
  2041. pWaitForVerticalBlank->bIsInVB = TRUE;
  2042. }
  2043. }
  2044. else
  2045. {
  2046. wfvbfn = pDevice->pDD->lpLcl->lpDDCB->HALDD.WaitForVerticalBlank;
  2047. wfvbhalfn = pDevice->pDD->lpLcl->lpDDCB->cbDDCallbacks.WaitForVerticalBlank;
  2048. dwRet = DDHAL_DRIVER_NOTHANDLED;
  2049. if( wfvbhalfn != NULL )
  2050. {
  2051. DDHAL_WAITFORVERTICALBLANKDATA wfvbd;
  2052. wfvbd.WaitForVerticalBlank = wfvbhalfn;
  2053. wfvbd.lpDD = pDevice->pDD->lpLcl->lpGbl;
  2054. wfvbd.dwFlags = pWaitForVerticalBlank->dwFlags;
  2055. wfvbd.hEvent = (ULONG_PTR) NULL;
  2056. DOHALCALL( WaitForVerticalBlank, wfvbfn, wfvbd, dwRet, FALSE );
  2057. if (dwRet == DDHAL_DRIVER_HANDLED)
  2058. {
  2059. pWaitForVerticalBlank->ddRVal = MapLegacyResult(wfvbd.ddRVal);
  2060. if (wfvbd.ddRVal == DDERR_VERTICALBLANKINPROGRESS)
  2061. {
  2062. pWaitForVerticalBlank->ddRVal = DD_OK;
  2063. pWaitForVerticalBlank->bIsInVB = TRUE;
  2064. }
  2065. else
  2066. {
  2067. pWaitForVerticalBlank->bIsInVB = FALSE;
  2068. }
  2069. }
  2070. }
  2071. }
  2072. LEAVE_BOTH();
  2073. return dwRet;
  2074. }
  2075. void BuildSurfaceDesc( PD3D8_CREATESURFACEDATA pCreateSurface, DDSURFACEDESC2* pddsd2 )
  2076. {
  2077. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pCreateSurface->hDD;
  2078. LPDDRAWI_DIRECTDRAW_INT pdrv_int = pDevice->pDD;
  2079. HRESULT hr;
  2080. DWORD i;
  2081. PDDSURFACE pSurf;
  2082. LPDIRECTDRAWSURFACE lpDDSurface;
  2083. memset(pddsd2, 0, sizeof(DDSURFACEDESC2));
  2084. pddsd2->dwSize = sizeof( DDSURFACEDESC2 );
  2085. //dwCaps3==1 means 1 sample per pixel.
  2086. pddsd2->ddsCaps.dwCaps3 = DDSCAPS3_MULTISAMPLE_MASK & (DWORD) pCreateSurface->MultiSampleType;
  2087. // Convert all of the caps
  2088. switch (pCreateSurface->Type)
  2089. {
  2090. case D3DRTYPE_SURFACE:
  2091. if (pCreateSurface->dwUsage & D3DUSAGE_ALPHACHANNEL)
  2092. {
  2093. DPF(0,"Setting alphachannel");
  2094. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_ENABLEALPHACHANNEL;
  2095. }
  2096. if (pCreateSurface->dwUsage & D3DUSAGE_PRIMARYSURFACE)
  2097. {
  2098. // If we aren't creating a primary flip chain, then we
  2099. // don't have to do much here.
  2100. if (pCreateSurface->dwSCnt == 1)
  2101. {
  2102. pddsd2->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
  2103. }
  2104. else
  2105. {
  2106. pddsd2->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE |
  2107. DDSCAPS_COMPLEX |
  2108. DDSCAPS_FLIP |
  2109. DDSCAPS_3DDEVICE;
  2110. }
  2111. }
  2112. else if (pCreateSurface->dwUsage & D3DUSAGE_DEPTHSTENCIL)
  2113. {
  2114. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  2115. pddsd2->ddsCaps.dwCaps |= DDSCAPS_ZBUFFER;
  2116. }
  2117. else
  2118. {
  2119. pddsd2->ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
  2120. }
  2121. if (pCreateSurface->dwSCnt > 1)
  2122. {
  2123. pddsd2->dwBackBufferCount = pCreateSurface->dwSCnt - 1;
  2124. pddsd2->dwFlags |= DDSD_BACKBUFFERCOUNT;
  2125. pddsd2->ddsCaps.dwCaps |= DDSCAPS_COMPLEX;
  2126. }
  2127. break;
  2128. case D3DRTYPE_TEXTURE:
  2129. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  2130. if (pCreateSurface->dwSCnt > 1)
  2131. {
  2132. pddsd2->ddsCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
  2133. pddsd2->dwFlags |= DDSD_MIPMAPCOUNT;
  2134. pddsd2->dwMipMapCount = pCreateSurface->dwSCnt;
  2135. }
  2136. else
  2137. {
  2138. // To DDraw, a mipmap w/ one level is really only a texture
  2139. pddsd2->ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
  2140. }
  2141. if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
  2142. {
  2143. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
  2144. }
  2145. break;
  2146. case D3DRTYPE_CUBETEXTURE:
  2147. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  2148. pddsd2->ddsCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
  2149. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_CUBEMAP;
  2150. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_CUBEMAP_ALLFACES;
  2151. DDASSERT(pCreateSurface->dwSCnt >= 6);
  2152. DDASSERT((pCreateSurface->dwSCnt % 6) == 0);
  2153. if (pCreateSurface->dwSCnt > 6)
  2154. {
  2155. pddsd2->ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
  2156. pddsd2->dwFlags |= DDSD_MIPMAPCOUNT;
  2157. pddsd2->dwMipMapCount = pCreateSurface->dwSCnt / 6;
  2158. }
  2159. if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
  2160. {
  2161. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
  2162. }
  2163. break;
  2164. case D3DRTYPE_IMAGESURFACE:
  2165. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  2166. // Image surfaces are marked as textures since they have the
  2167. // greatest flexibility for formats. But they don't get
  2168. // a CreateSurfaceEx handle since they are never passed to
  2169. // a driver.
  2170. pddsd2->ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
  2171. break;
  2172. case D3DRTYPE_COMMANDBUFFER:
  2173. pddsd2->ddsCaps.dwCaps |= DDSCAPS_EXECUTEBUFFER;
  2174. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_COMMANDBUFFER;
  2175. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  2176. DDASSERT((pCreateSurface->dwUsage & D3DUSAGE_INTERNALBUFFER) == 0);
  2177. break;
  2178. case D3DRTYPE_VERTEXBUFFER:
  2179. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  2180. pddsd2->ddsCaps.dwCaps |= DDSCAPS_EXECUTEBUFFER;
  2181. if (!(pCreateSurface->dwUsage & D3DUSAGE_INTERNALBUFFER))
  2182. {
  2183. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_VERTEXBUFFER;
  2184. }
  2185. if (pDevice->DriverLevel >= 8)
  2186. {
  2187. if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
  2188. {
  2189. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
  2190. }
  2191. else
  2192. {
  2193. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTSTATIC;
  2194. }
  2195. }
  2196. break;
  2197. case D3DRTYPE_INDEXBUFFER:
  2198. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  2199. pddsd2->ddsCaps.dwCaps |= DDSCAPS_EXECUTEBUFFER;
  2200. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_INDEXBUFFER;
  2201. if (pDevice->DriverLevel >= 8)
  2202. {
  2203. if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
  2204. {
  2205. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
  2206. }
  2207. else
  2208. {
  2209. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTSTATIC;
  2210. }
  2211. }
  2212. break;
  2213. case D3DRTYPE_VOLUME:
  2214. // We don't create stand-alone volumes
  2215. DDASSERT(FALSE);
  2216. break;
  2217. case D3DRTYPE_VOLUMETEXTURE:
  2218. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  2219. pddsd2->ddsCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
  2220. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_VOLUME;
  2221. pddsd2->ddsCaps.dwCaps4 =
  2222. MAKELONG((WORD)(pCreateSurface->pSList[0].cpDepth),0);
  2223. if (pCreateSurface->dwSCnt > 1)
  2224. {
  2225. pddsd2->ddsCaps.dwCaps |= DDSCAPS_COMPLEX;
  2226. pddsd2->dwFlags |= DDSD_MIPMAPCOUNT;
  2227. }
  2228. pddsd2->dwMipMapCount = pCreateSurface->dwSCnt;
  2229. if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
  2230. {
  2231. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
  2232. }
  2233. break;
  2234. }
  2235. if (pCreateSurface->dwUsage & D3DUSAGE_RENDERTARGET)
  2236. {
  2237. pddsd2->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE;
  2238. }
  2239. if (pCreateSurface->dwUsage & D3DUSAGE_DEPTHSTENCIL)
  2240. {
  2241. pddsd2->ddsCaps.dwCaps |= DDSCAPS_ZBUFFER;
  2242. }
  2243. if (pDevice->DriverLevel >= 8)
  2244. {
  2245. if (pCreateSurface->dwUsage & D3DUSAGE_LOADONCE)
  2246. {
  2247. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_OPAQUE;
  2248. }
  2249. if (pCreateSurface->dwUsage & D3DUSAGE_WRITEONLY)
  2250. {
  2251. pddsd2->ddsCaps.dwCaps |= DDSCAPS_WRITEONLY;
  2252. }
  2253. // Specify new usages for DX8+ drivers
  2254. if (!(pCreateSurface->dwUsage & D3DUSAGE_LOCK) &&
  2255. !(pCreateSurface->dwUsage & D3DUSAGE_LOADONCE))
  2256. {
  2257. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_NOTUSERLOCKABLE;
  2258. }
  2259. if (pCreateSurface->dwUsage & D3DUSAGE_DISCARD)
  2260. {
  2261. DDASSERT(pCreateSurface->Type != D3DRTYPE_TEXTURE);
  2262. DDASSERT(pCreateSurface->Type != D3DRTYPE_CUBETEXTURE);
  2263. DDASSERT(pCreateSurface->Type != D3DRTYPE_VOLUMETEXTURE);
  2264. DDASSERT(pCreateSurface->Type != D3DRTYPE_VOLUME);
  2265. DDASSERT(pCreateSurface->Type != D3DRTYPE_VERTEXBUFFER);
  2266. DDASSERT(pCreateSurface->Type != D3DRTYPE_INDEXBUFFER);
  2267. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_DISCARDBACKBUFFER;
  2268. }
  2269. if (pCreateSurface->dwUsage & D3DUSAGE_POINTS)
  2270. {
  2271. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_POINTS;
  2272. }
  2273. if (pCreateSurface->dwUsage & D3DUSAGE_RTPATCHES)
  2274. {
  2275. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_RTPATCHES;
  2276. }
  2277. if (pCreateSurface->dwUsage & D3DUSAGE_NPATCHES)
  2278. {
  2279. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_NPATCHES;
  2280. }
  2281. }
  2282. else // Pre-DX8 driver
  2283. {
  2284. // We allow LOADONCE through only for textures
  2285. if ((pCreateSurface->Type == D3DRTYPE_TEXTURE) ||
  2286. (pCreateSurface->Type == D3DRTYPE_CUBETEXTURE) ||
  2287. (pCreateSurface->Type == D3DRTYPE_VOLUMETEXTURE) ||
  2288. (pCreateSurface->Type == D3DRTYPE_VOLUME))
  2289. {
  2290. if (pCreateSurface->dwUsage & D3DUSAGE_LOADONCE)
  2291. {
  2292. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_OPAQUE;
  2293. }
  2294. }
  2295. // We allow WRITEONLY through only for VBs
  2296. if (pCreateSurface->Type == D3DRTYPE_VERTEXBUFFER)
  2297. {
  2298. if (pCreateSurface->dwUsage & D3DUSAGE_WRITEONLY)
  2299. {
  2300. pddsd2->ddsCaps.dwCaps |= DDSCAPS_WRITEONLY;
  2301. }
  2302. }
  2303. }
  2304. switch (pCreateSurface->Pool)
  2305. {
  2306. case D3DPOOL_LOCALVIDMEM:
  2307. pddsd2->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
  2308. break;
  2309. case D3DPOOL_NONLOCALVIDMEM:
  2310. pddsd2->ddsCaps.dwCaps |= DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
  2311. break;
  2312. case D3DPOOL_SYSTEMMEM:
  2313. pddsd2->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
  2314. break;
  2315. case D3DPOOL_MANAGED:
  2316. // We should only see this for DX8+ drivers <kd>
  2317. DDASSERT(pDevice->DriverLevel >= 8);
  2318. pddsd2->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
  2319. pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_TEXTUREMANAGE;
  2320. break;
  2321. case D3DPOOL_DEFAULT:
  2322. pCreateSurface->Pool = D3DPOOL_LOCALVIDMEM;
  2323. pddsd2->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
  2324. break;
  2325. default:
  2326. /* Unknown Pool?? */
  2327. DDASSERT(FALSE);
  2328. break;
  2329. }
  2330. pddsd2->dwFlags |= DDSD_CAPS;
  2331. // Convert the pixel format:
  2332. if ((pCreateSurface->Format != D3DFMT_UNKNOWN) &&
  2333. (pCreateSurface->Format != D3DFMT_VERTEXDATA) &&
  2334. (pCreateSurface->Format != D3DFMT_INDEX16) &&
  2335. (pCreateSurface->Format != D3DFMT_INDEX32) &&
  2336. !(pddsd2->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
  2337. {
  2338. pddsd2->dwFlags |= DDSD_PIXELFORMAT;
  2339. // For non-textures, we want to promote X8R8G8B8 to A8R8G8B8 in some cases;
  2340. // this allows things like RTs and Backbuffers to get created matching the
  2341. // primary which is more consistent with typical DX7 usage.
  2342. if (FormatCompatibleWithDisplayFormat(pDevice, (D3DFORMAT)pCreateSurface->Format) &&
  2343. (pCreateSurface->Type == D3DRTYPE_SURFACE))
  2344. {
  2345. //Surface looks like primary:
  2346. ConvertToOldFormat(&pddsd2->ddpfPixelFormat, pDevice->DisplayFormatWithAlpha);
  2347. }
  2348. else
  2349. {
  2350. ConvertToOldFormat(&pddsd2->ddpfPixelFormat, (D3DFORMAT)pCreateSurface->Format);
  2351. }
  2352. }
  2353. if (!(pddsd2->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
  2354. {
  2355. pddsd2->dwHeight = pCreateSurface->pSList[0].cpHeight;
  2356. pddsd2->dwWidth = pCreateSurface->pSList[0].cpWidth;
  2357. pddsd2->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
  2358. if (pddsd2->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER)
  2359. {
  2360. pddsd2->dwHeight = 0;
  2361. pddsd2->dwFlags &= ~DDSD_HEIGHT;
  2362. }
  2363. }
  2364. if (pCreateSurface->Type == D3DRTYPE_VERTEXBUFFER)
  2365. {
  2366. pddsd2->dwFVF = pCreateSurface->dwFVF;
  2367. pddsd2->dwFlags |= DDSD_FVF;
  2368. }
  2369. if (pddsd2->ddsCaps.dwCaps2 & DDSCAPS2_VOLUME)
  2370. {
  2371. pddsd2->dwDepth = pCreateSurface->pSList[0].cpDepth;
  2372. pddsd2->dwFlags |= DDSD_DEPTH;
  2373. }
  2374. }
  2375. DWORD InitSoftwareSurface(PD3D8_CREATESURFACEDATA pCreateSurface,
  2376. DWORD SurfIndex,
  2377. DDSURFACEDESC2* pddsd2,
  2378. DDSURFACE* pSurf,
  2379. DDSURFACE* pPrevious)
  2380. {
  2381. LPDDRAWI_DDRAWSURFACE_INT pInt;
  2382. LPDDRAWI_DDRAWSURFACE_LCL pLcl;
  2383. BYTE * pTemp;
  2384. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pCreateSurface->hDD;
  2385. pInt = MemAlloc( sizeof(DDRAWI_DDRAWSURFACE_LCL) +
  2386. sizeof(DDRAWI_DDRAWSURFACE_GBL) +
  2387. sizeof(DDRAWI_DDRAWSURFACE_MORE) +
  2388. sizeof(DDRAWI_DDRAWSURFACE_INT));
  2389. if (pInt == NULL)
  2390. {
  2391. return DDERR_OUTOFMEMORY;
  2392. }
  2393. pTemp = (BYTE*) pInt;
  2394. pTemp += sizeof(DDRAWI_DDRAWSURFACE_INT);
  2395. pInt->lpLcl = (LPDDRAWI_DDRAWSURFACE_LCL) pTemp;
  2396. pLcl = pInt->lpLcl;
  2397. pTemp += sizeof(DDRAWI_DDRAWSURFACE_LCL);
  2398. pLcl->lpGbl = (LPDDRAWI_DDRAWSURFACE_GBL) pTemp;
  2399. pTemp += sizeof(DDRAWI_DDRAWSURFACE_GBL);
  2400. pLcl->lpSurfMore = (LPDDRAWI_DDRAWSURFACE_MORE) pTemp;
  2401. memcpy(&pInt->lpLcl->lpGbl->ddpfSurface, &pddsd2->ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  2402. if (pddsd2->dwFlags & DDSD_PIXELFORMAT)
  2403. {
  2404. pLcl->dwFlags |= DDRAWISURF_HASPIXELFORMAT;
  2405. }
  2406. pLcl->lpGbl->wWidth = (WORD) pCreateSurface->pSList[SurfIndex].cpWidth;
  2407. pLcl->lpGbl->wHeight = (WORD) pCreateSurface->pSList[SurfIndex].cpHeight;
  2408. pLcl->ddsCaps.dwCaps = pddsd2->ddsCaps.dwCaps;
  2409. pLcl->lpSurfMore->ddsCapsEx.dwCaps2 = pddsd2->ddsCaps.dwCaps2;
  2410. pLcl->lpSurfMore->ddsCapsEx.dwCaps3 = DDSCAPS3_MULTISAMPLE_MASK & (DWORD) pCreateSurface->MultiSampleType;
  2411. pLcl->lpSurfMore->ddsCapsEx.dwCaps4 = pddsd2->ddsCaps.dwCaps4;
  2412. pLcl->lpSurfMore->dwSurfaceHandle = pSurf->dwCookie;
  2413. pLcl->lpSurfMore->lpDD_lcl = pDevice->pSwDD->lpLcl;
  2414. if (pSurf->Pool == D3DPOOL_SYSTEMMEM)
  2415. {
  2416. pLcl->lpGbl->fpVidMem = (FLATPTR) pCreateSurface->pSList[SurfIndex].pbPixels;
  2417. pLcl->lpGbl->lPitch = pCreateSurface->pSList[SurfIndex].iPitch;
  2418. }
  2419. if ((pCreateSurface->Type == D3DRTYPE_VOLUME) ||
  2420. (pCreateSurface->Type == D3DRTYPE_VOLUMETEXTURE))
  2421. {
  2422. pLcl->lpGbl->lSlicePitch = pCreateSurface->pSList[SurfIndex].iSlicePitch;
  2423. pLcl->lpSurfMore->ddsCapsEx.dwCaps4 =
  2424. MAKELONG((WORD)(pCreateSurface->pSList[SurfIndex].cpDepth),0);
  2425. }
  2426. // If it is a cube-map face, fix up the face flags in caps2.
  2427. if (pCreateSurface->Type == D3DRTYPE_CUBETEXTURE)
  2428. {
  2429. int MipLevels;
  2430. if (pCreateSurface->dwSCnt>6)
  2431. pLcl->ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
  2432. MipLevels = pCreateSurface->dwSCnt/6; //since all faces are always present in DX8
  2433. DDASSERT(MipLevels>=1);
  2434. //the first n (where n is mip depth) faces are +x, etc.
  2435. pLcl->lpSurfMore->ddsCapsEx.dwCaps2 |= DDSCAPS2_CUBEMAP;
  2436. pLcl->lpSurfMore->ddsCapsEx.dwCaps2 &= ~(DDSCAPS2_CUBEMAP_ALLFACES);
  2437. pLcl->lpSurfMore->ddsCapsEx.dwCaps2 |=
  2438. dwOrderedFaces[SurfIndex/MipLevels];
  2439. //every MipLevels'th surface is a top-level face,
  2440. if (SurfIndex % MipLevels)
  2441. {
  2442. // Mark non-top levels as being a sub-level
  2443. pLcl->lpSurfMore->ddsCapsEx.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
  2444. }
  2445. }
  2446. // If it is a texture, fix up the flags in caps2.
  2447. else if ((pCreateSurface->Type == D3DRTYPE_TEXTURE) ||
  2448. (pCreateSurface->Type == D3DRTYPE_VOLUMETEXTURE) ||
  2449. (pCreateSurface->Type == D3DRTYPE_VOLUME))
  2450. {
  2451. if( SurfIndex > 0 )
  2452. {
  2453. pLcl->lpSurfMore->ddsCapsEx.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
  2454. }
  2455. }
  2456. pSurf->pTempHeavy = pInt;
  2457. return DD_OK;
  2458. }
  2459. /*****************************Private*Routine******************************\
  2460. * SelectAttachmentSurface
  2461. *
  2462. * Returns an index into the surface creation list that indicates which
  2463. * surface this surface should be attached to. For mipmap sublevels this is
  2464. * always the preceding surface. For cubemaps, each face attaches to the
  2465. * root face (element 0).
  2466. *
  2467. * History:
  2468. * 21-Mar-2000 -by- Jeff Noyle [jeffno]
  2469. * Wrote it.
  2470. \**************************************************************************/
  2471. #undef DPF_MODNAME
  2472. #define DPF_MODNAME "SelectAttachmentSurface"
  2473. UINT SelectAttachmentSurface(
  2474. PD3D8_CREATESURFACEDATA pCreateSurface,
  2475. UINT iThis)
  2476. {
  2477. //We should never be called to find the attachment from the root face.
  2478. DDASSERT( iThis > 0);
  2479. if ((pCreateSurface->Type == D3DRTYPE_CUBETEXTURE) &&
  2480. ((iThis % (pCreateSurface->dwSCnt/6)) == 0) //which means we're looking at a top-level face
  2481. )
  2482. {
  2483. //... so we attach this face to the root
  2484. return 0;
  2485. }
  2486. else
  2487. {
  2488. // nope its just a mip sublevel, so we attach to the previous
  2489. return iThis-1;
  2490. }
  2491. }
  2492. void ExtractLightweightInfo (DDSURFACE *pSurf, LPDDRAWI_DDRAWSURFACE_INT pInt)
  2493. {
  2494. LIGHTWEIGHTSURFACE* pLight = pSurf->Surface.pLight;
  2495. LPDDRAWI_DDRAWSURFACE_GBL_MORE lpGblMore;
  2496. pLight->LclFlags = pInt->lpLcl->dwFlags;
  2497. pLight->LclCaps1 = pInt->lpLcl->ddsCaps.dwCaps;
  2498. pLight->LclReserved1 = pInt->lpLcl->dwReserved1;
  2499. pLight->LclModeCreatedIn = pInt->lpLcl->dwModeCreatedIn;
  2500. pLight->LclBackBufferCount = pInt->lpLcl->dwBackBufferCount;
  2501. pLight->GblFlags = pInt->lpLcl->lpGbl->dwGlobalFlags;
  2502. pLight->GblPitch = pInt->lpLcl->lpGbl->lPitch;
  2503. if (pSurf->Pitch == 0)
  2504. {
  2505. pSurf->Pitch = pLight->GblPitch;
  2506. }
  2507. pLight->GblWidth = pInt->lpLcl->lpGbl->wWidth;
  2508. pLight->GblReserved1 = pInt->lpLcl->lpGbl->dwReserved1;
  2509. if (pLight->LclFlags & DDRAWISURF_HASPIXELFORMAT)
  2510. {
  2511. ConvertFromOldFormat(&pInt->lpLcl->lpGbl->ddpfSurface,
  2512. &pLight->GblFormat);
  2513. }
  2514. else
  2515. {
  2516. pLight->GblFormat = D3DFMT_UNKNOWN;
  2517. }
  2518. pLight->pGblVidMemHeap = pInt->lpLcl->lpGbl->lpVidMemHeap;
  2519. pLight->fpGblVidMem = pInt->lpLcl->lpGbl->fpVidMem;
  2520. pLight->MoreCaps2 = pInt->lpLcl->lpSurfMore->ddsCapsEx.dwCaps2;
  2521. pLight->MoreCaps3 = pInt->lpLcl->lpSurfMore->ddsCapsEx.dwCaps3;
  2522. pLight->MoreCaps4 = pInt->lpLcl->lpSurfMore->ddsCapsEx.dwCaps4;
  2523. pLight->MoreRgjunc = pInt->lpLcl->lpSurfMore->rgjunc;
  2524. if ((pLight->LclCaps1 & DDSCAPS_MIPMAP) ||
  2525. (pLight->MoreCaps2 & DDSCAPS2_VOLUME))
  2526. {
  2527. pLight->MoreMipMapCount = pInt->lpLcl->lpSurfMore->dwMipMapCount;
  2528. }
  2529. else
  2530. {
  2531. pLight->MoreFVF = pInt->lpLcl->lpSurfMore->dwFVF;
  2532. }
  2533. lpGblMore = GET_LPDDRAWSURFACE_GBL_MORE (pInt->lpLcl->lpGbl);
  2534. if (lpGblMore != NULL)
  2535. {
  2536. pLight->GblMoreDriverReserved = lpGblMore->dwDriverReserved;
  2537. pLight->GblMoreContentsStamp = lpGblMore->dwContentsStamp;
  2538. pLight->pGblMoreUnswappedDriverReserved = lpGblMore->lpvUnswappedDriverReserved;
  2539. pLight->fpGblMoreAliasOfVidMem = lpGblMore->fpAliasOfVidMem;
  2540. pLight->cGblMorePageUnlocks = lpGblMore->cPageUnlocks;
  2541. }
  2542. if (pLight->LclCaps1 & DDSCAPS_NONLOCALVIDMEM)
  2543. {
  2544. if (lpGblMore != NULL)
  2545. {
  2546. pLight->fpGblMorePhysicalVidMem = lpGblMore->fpPhysicalVidMem;
  2547. }
  2548. }
  2549. else if (pLight->LclCaps1 & DDSCAPS_LOCALVIDMEM)
  2550. {
  2551. if (lpGblMore != NULL)
  2552. {
  2553. pLight->fpGblMoreAliasedVidMem = lpGblMore->fpAliasedVidMem;
  2554. }
  2555. }
  2556. else
  2557. {
  2558. pLight->MoreBytesAllocated = pInt->lpLcl->lpSurfMore->dwBytesAllocated;
  2559. }
  2560. pSurf->Height = pInt->lpLcl->lpGbl->wHeight;
  2561. pSurf->dwCookie = pInt->lpLcl->lpSurfMore->dwSurfaceHandle;
  2562. }
  2563. void DiscardHeavyweightMemory( LPDDRAWI_DDRAWSURFACE_INT pInt)
  2564. {
  2565. if (pInt->lpLcl->lpSurfMore->slist != NULL)
  2566. {
  2567. MemFree (pInt->lpLcl->lpSurfMore->slist);
  2568. }
  2569. MemFree (pInt->lpLcl);
  2570. MemFree (pInt);
  2571. }
  2572. DWORD APIENTRY DdCreateSurface( PD3D8_CREATESURFACEDATA pCreateSurface )
  2573. {
  2574. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pCreateSurface->hDD;
  2575. LPDDRAWI_DIRECTDRAW_INT pdrv_int = pDevice->pDD;
  2576. HRESULT hr;
  2577. DWORD i;
  2578. PDDSURFACE pSurf;
  2579. LPDIRECTDRAWSURFACE lpDDSurface;
  2580. DWORD dwNumToCreate;
  2581. DDSURFACEDESC2 ddsd2;
  2582. DWORD NextWidth;
  2583. DWORD NextHeight;
  2584. DEFERREDCREATE* pDefCreate;
  2585. ENTER_DDRAW();
  2586. BuildSurfaceDesc (pCreateSurface, &ddsd2);
  2587. dwNumToCreate = pCreateSurface->dwSCnt;
  2588. // Allocate the internal surface structures for each surface in the chain
  2589. // and initialize it if we are not reusing the surface
  2590. if (!pCreateSurface->bReUse)
  2591. {
  2592. NextWidth = ddsd2.dwWidth;
  2593. NextHeight = ddsd2.dwHeight;
  2594. for (i = 0; i < dwNumToCreate; i++)
  2595. {
  2596. pSurf = (PDDSURFACE) MemAlloc(sizeof(DDSURFACE));
  2597. if (pSurf == NULL)
  2598. {
  2599. hr = DDERR_OUTOFMEMORY;
  2600. goto CreateErrorCleanup;
  2601. }
  2602. pSurf->Pool = pCreateSurface->Pool;
  2603. pSurf->Format = pCreateSurface->Format;
  2604. pSurf->Type = pCreateSurface->Type;
  2605. // For volume textures, we need to know the depth to handle lost
  2606. // devices (for everything else we need to height). To save space,
  2607. // we will re-use the same variable.
  2608. if ((pSurf->Type == D3DRTYPE_VOLUME) ||
  2609. (pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
  2610. {
  2611. pSurf->Height = pCreateSurface->pSList[i].cpDepth;
  2612. }
  2613. else
  2614. {
  2615. pSurf->Height = pCreateSurface->pSList[i].cpHeight;
  2616. }
  2617. pCreateSurface->pSList[i].hKernelHandle = (HANDLE) pSurf;
  2618. pSurf->pDevice = (PDDDEVICEHANDLE) pCreateSurface->hDD;
  2619. // DX6 drivers cannot handle deep mipmaps, but we want to hide this from
  2620. // the runtime, so we need to determine if the current level is a dummy
  2621. // level
  2622. if ((pDevice->DriverLevel == 6) &&
  2623. (ddsd2.ddsCaps.dwCaps & DDSCAPS_MIPMAP))
  2624. {
  2625. if ((pCreateSurface->pSList[i].cpWidth == NextWidth) &&
  2626. (pCreateSurface->pSList[i].cpHeight == NextHeight))
  2627. {
  2628. // This level is OK, so mark it as such
  2629. ddsd2.dwMipMapCount = i + 1;
  2630. }
  2631. else
  2632. {
  2633. pSurf->dwFlags |= DDSURFACE_DUMMY;
  2634. if (i == 1)
  2635. {
  2636. // If there's only one valid level, then don't call it
  2637. // a mipmap
  2638. ddsd2.ddsCaps.dwCaps &= ~DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
  2639. ddsd2.dwFlags &= ~DDSD_MIPMAPCOUNT;
  2640. }
  2641. }
  2642. NextWidth /= 2;
  2643. NextHeight /= 2;
  2644. }
  2645. // Now figure out if this is a software driver
  2646. // surface, or a HAL surface.
  2647. if (IS_SOFTWARE_DRIVER(pCreateSurface->hDD) &&
  2648. !(pCreateSurface->dwUsage & D3DUSAGE_PRIMARYSURFACE) &&
  2649. !(pCreateSurface->dwUsage & D3DUSAGE_OFFSCREENPLAIN))
  2650. {
  2651. // If they are running w/ a software driver (refrast, RGB HEL, etc.),
  2652. // we will not allow any surfaces to be created in video memory except
  2653. // for the primary flipping chain. And also for surfaces marked
  2654. // D3DUSAGE_OFFSCREENPLAIN (which are used for the cursors)
  2655. pSurf->dwFlags |= DDSURFACE_SOFTWARE;
  2656. }
  2657. else
  2658. {
  2659. pSurf->dwFlags |= DDSURFACE_HAL;
  2660. }
  2661. if (pCreateSurface->bTreatAsVidMem == TRUE)
  2662. {
  2663. // For objects that should be treated as non-persistent
  2664. // i.e. Reset fails unless these are all freed; we
  2665. // set a flag here and check it in DoVidMemSurfacesExist()
  2666. pSurf->dwFlags |= DDSURFACE_TREATASVIDMEM;
  2667. }
  2668. if (pDevice->bLightweight && IsLightweightSurface(pDevice, &ddsd2, pCreateSurface->Format))
  2669. {
  2670. pSurf->dwFlags |= DDSURFACE_LIGHTWEIGHT;
  2671. pSurf->Surface.pLight = (LIGHTWEIGHTSURFACE*) MemAlloc(sizeof(LIGHTWEIGHTSURFACE));
  2672. if (pSurf->Surface.pLight == NULL)
  2673. {
  2674. hr = DDERR_OUTOFMEMORY;
  2675. goto CreateErrorCleanup;
  2676. }
  2677. }
  2678. else
  2679. {
  2680. pSurf->dwFlags |= DDSURFACE_HEAVYWEIGHT;
  2681. }
  2682. // Software surfaces are special cased because we want to call the software
  2683. // driver for Create and CreateEx rather than the real driver.
  2684. if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  2685. {
  2686. if ((ddsd2.ddsCaps.dwCaps & (DDSCAPS_TEXTURE |
  2687. DDSCAPS_EXECUTEBUFFER |
  2688. DDSCAPS_3DDEVICE |
  2689. DDSCAPS_ZBUFFER)) &&
  2690. (pCreateSurface->Type != D3DRTYPE_IMAGESURFACE))
  2691. {
  2692. pSurf->dwCookie = GetDX7SurfaceHandle(pCreateSurface->hDD);
  2693. }
  2694. hr = InitSoftwareSurface(pCreateSurface,
  2695. i,
  2696. &ddsd2,
  2697. pSurf,
  2698. i > 0 ? pCreateSurface->pSList[i].hKernelHandle : NULL);
  2699. if (hr != DD_OK)
  2700. {
  2701. goto CreateErrorCleanup;
  2702. }
  2703. }
  2704. }
  2705. }
  2706. else
  2707. {
  2708. DDASSERT(pCreateSurface->Pool == D3DPOOL_MANAGED);
  2709. }
  2710. pSurf = (DDSURFACE*) pCreateSurface->pSList[0].hKernelHandle;
  2711. if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  2712. {
  2713. if (pCreateSurface->Pool != D3DPOOL_SYSTEMMEM)
  2714. {
  2715. // There is a descrepancy in the surface desc that CreateSurface
  2716. // expects and the driver expects, so we will adjust it here for
  2717. // the driver.
  2718. if ((ddsd2.dwFlags & DDSD_WIDTH) &&
  2719. !(ddsd2.dwFlags & DDSD_HEIGHT))
  2720. {
  2721. ddsd2.dwFlags |= DDSD_HEIGHT;
  2722. ddsd2.dwHeight = 1;
  2723. }
  2724. hr = SwDDICreateSurface(pCreateSurface, &ddsd2);
  2725. if (hr != DD_OK)
  2726. {
  2727. goto CreateErrorCleanup;
  2728. }
  2729. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  2730. {
  2731. ((DDSURFACE*)pCreateSurface->pSList[i].hKernelHandle)->dwFlags |=
  2732. DDSURFACE_CREATECOMPLETE;
  2733. }
  2734. }
  2735. // We've already created the object so all
  2736. // we have to do is call CreateSurfaceEx
  2737. if (pSurf->dwCookie != 0)
  2738. {
  2739. // If it's a software driver, we may need to attach surfaces
  2740. for (i = 1; i < pCreateSurface->dwSCnt; i++)
  2741. {
  2742. SwDDIAttachSurfaces (
  2743. ((DDSURFACE*)pCreateSurface->pSList[
  2744. SelectAttachmentSurface(pCreateSurface,i)
  2745. ].hKernelHandle)->pTempHeavy->lpLcl,
  2746. ((DDSURFACE*)pCreateSurface->pSList[i].hKernelHandle)->pTempHeavy->lpLcl);
  2747. }
  2748. SwDDICreateSurfaceEx (pDevice->pSwDD->lpLcl,
  2749. pSurf->pTempHeavy->lpLcl);
  2750. pSurf->dwFlags |= DDSURFACE_CREATEEX;
  2751. }
  2752. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  2753. {
  2754. LPATTACHLIST pAttach;
  2755. LPATTACHLIST pAttachTemp;
  2756. pSurf = (DDSURFACE*)pCreateSurface->pSList[i].hKernelHandle;
  2757. // For a sw driver, always destroy the attached list now.
  2758. // It serves no purpose after CreateSurfaceEx is called.
  2759. if (pSurf->pTempHeavy->lpLcl->lpAttachList != NULL)
  2760. {
  2761. pAttach = pSurf->pTempHeavy->lpLcl->lpAttachList->lpLink;
  2762. while (pAttach != NULL)
  2763. {
  2764. pAttachTemp = pAttach;
  2765. pAttach = pAttach->lpLink;
  2766. MemFree(pAttachTemp);
  2767. }
  2768. MemFree(pSurf->pTempHeavy->lpLcl->lpAttachList);
  2769. pSurf->pTempHeavy->lpLcl->lpAttachList = NULL;
  2770. }
  2771. if (pSurf->pTempHeavy->lpLcl->lpAttachListFrom != NULL)
  2772. {
  2773. pAttach = pSurf->pTempHeavy->lpLcl->lpAttachListFrom->lpLink;
  2774. while (pAttach != NULL)
  2775. {
  2776. pAttachTemp = pAttach;
  2777. pAttach = pAttach->lpLink;
  2778. MemFree(pAttachTemp);
  2779. }
  2780. MemFree(pSurf->pTempHeavy->lpLcl->lpAttachListFrom);
  2781. pSurf->pTempHeavy->lpLcl->lpAttachListFrom = NULL;
  2782. }
  2783. pSurf->iSlicePitch = pSurf->pTempHeavy->lpLcl->lpGbl->lSlicePitch;
  2784. pSurf->pTempHeavy->lpLcl->lpGbl->lSlicePitch = 0;
  2785. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  2786. {
  2787. ExtractLightweightInfo (pSurf, pSurf->pTempHeavy);
  2788. MemFree (pSurf->pTempHeavy);
  2789. }
  2790. else
  2791. {
  2792. pSurf->Surface.pHeavy = pSurf->pTempHeavy;
  2793. }
  2794. pSurf->pTempHeavy = NULL;
  2795. }
  2796. }
  2797. else
  2798. {
  2799. LPDDSURFACEINFO pSysMem = NULL;
  2800. BOOL bLost;
  2801. // If it's a sysmem surface, we want them to use the memory that we
  2802. // have already allocated, so we need to setup an array of pointers.
  2803. if ((pCreateSurface->Pool == D3DPOOL_SYSTEMMEM) ||
  2804. (ddsd2.ddsCaps.dwCaps2 & DDSCAPS2_VOLUME))
  2805. {
  2806. pSysMem = pCreateSurface->pSList;
  2807. }
  2808. // If we are creating a vidmem surface, we need to check for device lost
  2809. // and if it's lost, we don't want to create the surface, but to instead
  2810. // allocate a private buffer that we can return when lock is called. We
  2811. // do not want to fail the call just because the device is lost.
  2812. ENTER_WIN16LOCK();
  2813. bLost = CheckForDeviceLost(pDevice);
  2814. // Special early out. If reuse is true, we haven't done anything yet (to
  2815. // verify this, trace code above) so all we need to do is to return SURFACELOST
  2816. // and not worry about jumping to CreateErrorCleanup below.
  2817. if (bLost && pCreateSurface->bReUse)
  2818. {
  2819. DDASSERT(!IS_SOFTWARE_DRIVER_SURFACE(pSurf));
  2820. DDASSERT(pCreateSurface->Pool == D3DPOOL_MANAGED);
  2821. LEAVE_WIN16LOCK();
  2822. LEAVE_DDRAW();
  2823. return DDERR_SURFACELOST;
  2824. }
  2825. if ((pCreateSurface->Pool != D3DPOOL_SYSTEMMEM) &&
  2826. bLost)
  2827. {
  2828. DWORD j;
  2829. DDASSERT(pCreateSurface->bReUse == FALSE);
  2830. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  2831. {
  2832. pSurf = (PDDSURFACE) pCreateSurface->pSList[i].hKernelHandle;
  2833. pSurf->Pitch = pCreateSurface->pSList[i].cpWidth * 8;
  2834. pSurf->iSlicePitch = pSurf->Pitch * pCreateSurface->pSList[i].cpHeight;
  2835. if (!(pSurf->dwFlags & DDSURFACE_DUMMY))
  2836. {
  2837. if ((pSurf->Type == D3DRTYPE_VOLUME) ||
  2838. (pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
  2839. {
  2840. pSurf->fpVidMem = (char*)
  2841. MemAlloc(pSurf->iSlicePitch * pSurf->Height);
  2842. }
  2843. else
  2844. {
  2845. pSurf->fpVidMem = (char*)
  2846. MemAlloc(pSurf->Pitch * pSurf->Height);
  2847. }
  2848. if (pSurf->fpVidMem == (char*) NULL)
  2849. {
  2850. DWORD j;
  2851. for (j = 0; j < i; j++)
  2852. {
  2853. pSurf = (PDDSURFACE) pCreateSurface->pSList[i].hKernelHandle;
  2854. MemFree (pSurf->fpVidMem);
  2855. }
  2856. hr = DDERR_OUTOFMEMORY;
  2857. LEAVE_WIN16LOCK();
  2858. goto CreateErrorCleanup;
  2859. }
  2860. else
  2861. {
  2862. pSurf->dwFlags |= DDSURFACE_SYSMEMALLOCATED;
  2863. }
  2864. }
  2865. }
  2866. // If the surface is driver managed, we save the creation info so that
  2867. // we can retry the creation at reset time
  2868. if (ddsd2.ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
  2869. {
  2870. DDASSERT(pCreateSurface->Pool == D3DPOOL_MANAGED);
  2871. pDefCreate = (PDEFERREDCREATE)MemAlloc(sizeof(DEFERREDCREATE));
  2872. if (pDefCreate == NULL)
  2873. {
  2874. // Cleanup stuff that we allocated above
  2875. for (i = 0; i < pCreateSurface->dwSCnt; ++i)
  2876. {
  2877. pSurf = (PDDSURFACE) pCreateSurface->pSList[i].hKernelHandle;
  2878. MemFree(pSurf->fpVidMem);
  2879. pSurf->dwFlags &= ~DDSURFACE_SYSMEMALLOCATED;
  2880. }
  2881. hr = DDERR_OUTOFMEMORY;
  2882. LEAVE_WIN16LOCK();
  2883. goto CreateErrorCleanup;
  2884. }
  2885. // Copy
  2886. pDefCreate->CreateData = *pCreateSurface;
  2887. pDefCreate->CreateData.pSList = (LPDDSURFACEINFO)MemAlloc(sizeof(DDSURFACEINFO) * pCreateSurface->dwSCnt);
  2888. if (pDefCreate->CreateData.pSList == NULL)
  2889. {
  2890. // Cleanup stuff that we allocated above
  2891. MemFree(pDefCreate);
  2892. for (i = 0; i < pCreateSurface->dwSCnt; ++i)
  2893. {
  2894. pSurf = (PDDSURFACE) pCreateSurface->pSList[i].hKernelHandle;
  2895. MemFree(pSurf->fpVidMem);
  2896. pSurf->dwFlags &= ~DDSURFACE_SYSMEMALLOCATED;
  2897. }
  2898. hr = DDERR_OUTOFMEMORY;
  2899. LEAVE_WIN16LOCK();
  2900. goto CreateErrorCleanup;
  2901. }
  2902. // Copy
  2903. CopyMemory(pDefCreate->CreateData.pSList, pCreateSurface->pSList, sizeof(DDSURFACEINFO) * pCreateSurface->dwSCnt);
  2904. // Linkup
  2905. pDefCreate->pNext = ((PDDDEVICEHANDLE)pCreateSurface->hDD)->pDeferList;
  2906. ((PDDDEVICEHANDLE)pCreateSurface->hDD)->pDeferList = pDefCreate;
  2907. // *************************MEMORY LEAK WARNING*********************** //
  2908. // The DEFERREDCREATE and DDSURFACEINFO allocations above will
  2909. // not be cleaned up immediately if there is a failure after this
  2910. // point. As of 5/2001, there is no case in which we will fail after
  2911. // this point. (snene)
  2912. // ******************************************************************* //
  2913. }
  2914. }
  2915. else
  2916. {
  2917. DWORD DX8Flags = DX8SFLAG_DX8;
  2918. // If we are creating a sysmem surface while lost, we don't want
  2919. // want to call the driver to create the SurfaceEx handle.
  2920. if (bLost)
  2921. {
  2922. DX8Flags |= DX8SFLAG_ISLOST;
  2923. }
  2924. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  2925. {
  2926. DX8Flags |= DX8SFLAG_ISLIGHTWEIGHT;
  2927. }
  2928. if (pCreateSurface->Type == D3DRTYPE_IMAGESURFACE)
  2929. {
  2930. DX8Flags |= DX8SFLAG_IMAGESURF;
  2931. }
  2932. hr = DD_CreateSurface4_Main( (LPDIRECTDRAW) pdrv_int,
  2933. &ddsd2,
  2934. &lpDDSurface,
  2935. NULL,
  2936. TRUE,
  2937. pSysMem,
  2938. DX8Flags);
  2939. if (hr != DD_OK)
  2940. {
  2941. LEAVE_WIN16LOCK();
  2942. goto CreateErrorCleanup;
  2943. }
  2944. // If we let DDraw decide between local vidmem / AGP, then we need
  2945. // to figure out which one it chose.
  2946. if (((LPDDRAWI_DDRAWSURFACE_INT)lpDDSurface)->lpLcl->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
  2947. {
  2948. pCreateSurface->Pool = D3DPOOL_NONLOCALVIDMEM;
  2949. for (i = 0; i < dwNumToCreate; i++)
  2950. {
  2951. pSurf = (DDSURFACE*) pCreateSurface->pSList[i].hKernelHandle;
  2952. pSurf->Pool = D3DPOOL_NONLOCALVIDMEM;
  2953. }
  2954. }
  2955. // Everything has worked
  2956. //Find the pointer to the attached heavyweight surface for
  2957. //each face, mip level, back buffer etc.
  2958. switch(pCreateSurface->Type)
  2959. {
  2960. case D3DRTYPE_VERTEXBUFFER :
  2961. case D3DRTYPE_INDEXBUFFER :
  2962. case D3DRTYPE_COMMANDBUFFER :
  2963. //these types have no attachments
  2964. DDASSERT(0 == ( (LPDDRAWI_DDRAWSURFACE_INT)lpDDSurface)->lpLcl->lpAttachList );
  2965. //but we need to fall through and set the pHeavy for the first one.
  2966. case D3DRTYPE_SURFACE :
  2967. case D3DRTYPE_IMAGESURFACE :
  2968. case D3DRTYPE_VOLUME :
  2969. case D3DRTYPE_TEXTURE :
  2970. case D3DRTYPE_VOLUMETEXTURE :
  2971. {
  2972. LPDDRAWI_DDRAWSURFACE_INT lpTemp;
  2973. LPDDRAWI_DDRAWSURFACE_INT lpTemp1;
  2974. lpTemp = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
  2975. //these types are allocated in a linear list of attachments
  2976. for (i = 0; i < dwNumToCreate; i++)
  2977. {
  2978. pSurf = (DDSURFACE*) pCreateSurface->pSList[i].hKernelHandle;
  2979. DDASSERT(!(pSurf->dwFlags & DDSURFACE_DUMMY)); //cuz not DX6 driver
  2980. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  2981. {
  2982. ExtractLightweightInfo (pSurf, lpTemp);
  2983. }
  2984. else
  2985. {
  2986. pSurf->Surface.pHeavy = lpTemp;
  2987. }
  2988. lpTemp1 = lpTemp;
  2989. if (lpTemp->lpLcl->lpAttachList)
  2990. lpTemp = lpTemp->lpLcl->lpAttachList->lpIAttached;
  2991. pSurf->iSlicePitch = lpTemp1->lpLcl->lpGbl->lSlicePitch;
  2992. lpTemp1->lpLcl->lpGbl->lSlicePitch = 0;
  2993. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  2994. {
  2995. if (lpTemp1->lpLcl->lpAttachList != NULL)
  2996. {
  2997. MemFree(lpTemp1->lpLcl->lpAttachList);
  2998. }
  2999. if (lpTemp1->lpLcl->lpAttachListFrom != NULL)
  3000. {
  3001. MemFree(lpTemp1->lpLcl->lpAttachListFrom);
  3002. }
  3003. DiscardHeavyweightMemory(lpTemp1);
  3004. }
  3005. }
  3006. }
  3007. break;
  3008. case D3DRTYPE_CUBETEXTURE :
  3009. //cubes are the hard buggers.
  3010. {
  3011. int face;
  3012. DWORD cLevels = dwNumToCreate/6;
  3013. for(face=0; face<6; face++)
  3014. {
  3015. LPDDRAWI_DDRAWSURFACE_INT lpTemp;
  3016. lpTemp = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
  3017. //point lpTemp to the next top-level face (which will be
  3018. //attached to the face returned by create-surface)
  3019. //(we are already pointing thereat if it's face 0)
  3020. if (face)
  3021. {
  3022. LPATTACHLIST pal;
  3023. pal = lpTemp->lpLcl->lpAttachList;
  3024. do
  3025. {
  3026. lpTemp = pal->lpIAttached;
  3027. pal = pal->lpLink;
  3028. }
  3029. while(0 == (lpTemp->lpLcl->lpSurfMore->ddsCapsEx.dwCaps2 & dwOrderedFaces[face]));
  3030. }
  3031. //for each face, we run down the attachment list
  3032. //which are allocated in a linear list of attachments
  3033. for (i = 0; i < cLevels; i++)
  3034. {
  3035. pSurf = (DDSURFACE*) pCreateSurface->pSList[face*cLevels+i].hKernelHandle;
  3036. DDASSERT(!(pSurf->dwFlags & DDSURFACE_DUMMY)); //cuz not DX6 driver
  3037. pSurf->iSlicePitch = lpTemp->lpLcl->lpGbl->lSlicePitch;
  3038. lpTemp->lpLcl->lpGbl->lSlicePitch = 0;
  3039. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  3040. {
  3041. ExtractLightweightInfo (pSurf, lpTemp);
  3042. }
  3043. else
  3044. {
  3045. pSurf->Surface.pHeavy = lpTemp;
  3046. }
  3047. if ((face == 0) && (i == 0) && (cLevels > 1))
  3048. {
  3049. // Special hack for finding mip-levels
  3050. // of first face; the mip-levels for the pos-x
  3051. // face are actually near the the end of the
  3052. // list (interposed by the top-levels of the
  3053. // other 5 faces)
  3054. int j;
  3055. LPATTACHLIST pal = lpTemp->lpLcl->lpAttachList;
  3056. for (j = 0; j < 5; j++)
  3057. {
  3058. pal = pal->lpLink;
  3059. }
  3060. lpTemp = pal->lpIAttached;
  3061. // Check we found what we were looking for
  3062. DDASSERT(lpTemp->lpLcl->lpSurfMore->ddsCapsEx.dwCaps2 & dwOrderedFaces[face]);
  3063. }
  3064. else if (lpTemp->lpLcl->lpAttachList)
  3065. {
  3066. // Normal case; i.e. just go to the surface we
  3067. // are directly attached to
  3068. lpTemp = lpTemp->lpLcl->lpAttachList->lpIAttached;
  3069. }
  3070. }
  3071. }
  3072. // If it's a lightweight surface, now we need to free
  3073. // all of the heavyweight memory
  3074. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  3075. {
  3076. LPDDRAWI_DDRAWSURFACE_INT lpTemp;
  3077. LPATTACHLIST pal;
  3078. LPATTACHLIST pNextPal;
  3079. LPATTACHLIST pFaceList;
  3080. LPATTACHLIST pTemp;
  3081. lpTemp = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
  3082. pal = lpTemp->lpLcl->lpAttachList;
  3083. DiscardHeavyweightMemory(lpTemp);
  3084. while (pal != NULL)
  3085. {
  3086. pNextPal = pal->lpLink;
  3087. pFaceList = pal;
  3088. while (pFaceList != NULL)
  3089. {
  3090. if (pFaceList->lpAttached->lpAttachListFrom)
  3091. {
  3092. MemFree (pFaceList->lpAttached->lpAttachListFrom);
  3093. }
  3094. pTemp = pFaceList->lpAttached->lpAttachList;
  3095. DiscardHeavyweightMemory(pFaceList->lpIAttached);
  3096. MemFree(pFaceList);
  3097. pFaceList = pTemp;
  3098. }
  3099. pal = pNextPal;
  3100. }
  3101. }
  3102. }
  3103. break;
  3104. default:
  3105. DDASSERT(0); //unexpected type
  3106. break;
  3107. }
  3108. for (i = 0; i < dwNumToCreate; i++)
  3109. {
  3110. DWORD j;
  3111. pSurf = (DDSURFACE*) pCreateSurface->pSList[i].hKernelHandle;
  3112. if (i == 0)
  3113. {
  3114. pSurf->dwFlags |= DDSURFACE_ROOT;
  3115. }
  3116. if (pSurf->dwFlags & DDSURFACE_HEAVYWEIGHT)
  3117. {
  3118. pSurf->Pitch = pSurf->Surface.pHeavy->lpLcl->lpGbl->lPitch;
  3119. if (!(pSurf->dwFlags & DDSURFACE_DUMMY))
  3120. {
  3121. if (i == 0)
  3122. {
  3123. if (DDSCAPS_PRIMARYSURFACE &
  3124. pSurf->Surface.pHeavy->lpLcl->ddsCaps.dwCaps)
  3125. {
  3126. if (!(DDRAWILCL_HASEXCLUSIVEMODE & pdrv_int->lpLcl->dwLocalFlags))
  3127. {
  3128. LPDIRECTDRAWCLIPPER pcClipper;
  3129. if (SUCCEEDED(DD_CreateClipper((LPDIRECTDRAW) pdrv_int,
  3130. 0, &pcClipper, NULL)))
  3131. {
  3132. if (pdrv_int->lpLcl->hWnd)
  3133. DD_Clipper_SetHWnd(pcClipper, 0, (HWND) pdrv_int->lpLcl->hWnd);
  3134. DD_Surface_SetClipper(lpDDSurface, pcClipper);
  3135. DPF(10,"Setting Clipper=%08lx with hWnd=%08lx to Primary"
  3136. " Surface", pcClipper, pdrv_int->lpLcl->hWnd);
  3137. DD_Clipper_Release(pcClipper);
  3138. }
  3139. }
  3140. }
  3141. }
  3142. }
  3143. pCreateSurface->pSList[i].hKernelHandle = (HANDLE) pSurf;
  3144. }
  3145. // If this is a DX6+ driver, the above CreateSurface call would
  3146. // have created the ExSurface and assigned a driver handle value.
  3147. // If it's a DX6 driver, however, we need to create the texture
  3148. // handle ourselves.
  3149. if (pDevice->DriverLevel > 6)
  3150. {
  3151. if (pSurf->dwFlags & DDSURFACE_HEAVYWEIGHT)
  3152. {
  3153. pSurf->dwCookie = pSurf->Surface.pHeavy->lpLcl->lpSurfMore->dwSurfaceHandle;
  3154. }
  3155. if (pSurf->dwCookie &&
  3156. bLost &&
  3157. (pSurf->dwFlags & DDSURFACE_ROOT))
  3158. {
  3159. // We've created the surface, but we can't create the
  3160. // surface Ex handle yet, so we will defer that creation until later.
  3161. pSurf->dwFlags |= DDSURFACE_DEFERCREATEEX;
  3162. }
  3163. }
  3164. else if ((pSurf->dwFlags & DDSURFACE_ROOT) &&
  3165. (pSurf->Type == D3DRTYPE_TEXTURE))
  3166. {
  3167. // Don't create a texture handle if the surface is in sysmem
  3168. // and the device doesn't texture from sysmem
  3169. if ((pCreateSurface->Pool != D3DPOOL_SYSTEMMEM) ||
  3170. pDevice->bCanTextureSysmem)
  3171. {
  3172. D3DHAL_TEXTURECREATEDATA data;
  3173. DWORD ret;
  3174. if (pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureCreate == NULL)
  3175. {
  3176. hr = DDERR_UNSUPPORTED;
  3177. LEAVE_WIN16LOCK();
  3178. goto CreateErrorCleanup;
  3179. }
  3180. if (bLost)
  3181. {
  3182. // We cannot create the texture handle at this time,
  3183. // so we will do it later.
  3184. pSurf->dwFlags |= DDSURFACE_DEFERCREATETEXHANDLE;
  3185. pDevice->pContext->dwFlags |= DDCONTEXT_DEFEREDTEXTUREHANDLES;
  3186. }
  3187. else
  3188. {
  3189. // If it's a palettized texture, we need to associate a
  3190. // palette before calling TextureCreate or else some
  3191. // drivers (Rage128) will fault.
  3192. if ((pCreateSurface->Format == D3DFMT_P8) ||
  3193. (pCreateSurface->Format == D3DFMT_A8P8))
  3194. {
  3195. if (pDevice->pDefaultPalette == NULL)
  3196. {
  3197. {
  3198. PALETTEENTRY ColorTable[256];
  3199. int i;
  3200. for (i = 0; i < 256; i++)
  3201. {
  3202. ColorTable[i].peRed = (UCHAR) i;
  3203. ColorTable[i].peGreen = (UCHAR) i;
  3204. ColorTable[i].peBlue = (UCHAR) i;
  3205. }
  3206. DD_CreatePalette ((LPDIRECTDRAW) pDevice->pDD,
  3207. DDPCAPS_8BIT,
  3208. ColorTable,
  3209. &pDevice->pDefaultPalette,
  3210. NULL);
  3211. }
  3212. if (pDevice->pDefaultPalette == NULL)
  3213. {
  3214. DPF_ERR("Unable to create default palette");
  3215. LEAVE_WIN16LOCK();
  3216. hr = DDERR_OUTOFMEMORY;
  3217. goto CreateErrorCleanup;
  3218. }
  3219. }
  3220. hr = DD_Surface_SetPalette(lpDDSurface,
  3221. pDevice->pDefaultPalette);
  3222. if (hr != DD_OK)
  3223. {
  3224. DPF_ERR("Unable to set default palette");
  3225. LEAVE_WIN16LOCK();
  3226. goto CreateErrorCleanup;
  3227. }
  3228. }
  3229. memset(&data, 0, sizeof(D3DHAL_TEXTURECREATEDATA));
  3230. data.dwhContext = pDevice->pContext->Context;
  3231. data.lpDDS = lpDDSurface;
  3232. CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
  3233. pDevice,
  3234. pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureCreate,
  3235. &data);
  3236. if (ret != DDHAL_DRIVER_HANDLED || data.ddrval != DD_OK)
  3237. {
  3238. DPF_ERR("HAL failed to handle TextureCreate");
  3239. LEAVE_WIN16LOCK();
  3240. hr = data.ddrval;
  3241. goto CreateErrorCleanup;
  3242. }
  3243. pSurf->dwCookie = data.dwHandle;
  3244. pSurf->dwFlags |= DDSURFACE_DX6HANDLE;
  3245. }
  3246. }
  3247. }
  3248. }
  3249. }
  3250. LEAVE_WIN16LOCK();
  3251. }
  3252. // Now insert this into our linked list
  3253. // If re-using, then we are already on the list so don't do anything
  3254. if (!pCreateSurface->bReUse)
  3255. {
  3256. for (i = 0; i < dwNumToCreate; i++)
  3257. {
  3258. ((PDDSURFACE)(pCreateSurface->pSList[i].hKernelHandle))->pNext =
  3259. pDevice->pSurfList;
  3260. ((PDDSURFACE)(pCreateSurface->pSList[i].hKernelHandle))->pPrevious =
  3261. NULL;
  3262. if (pDevice->pSurfList != NULL)
  3263. {
  3264. pDevice->pSurfList->pPrevious = (PDDSURFACE)(pCreateSurface->pSList[i].hKernelHandle);
  3265. }
  3266. pDevice->pSurfList = (PDDSURFACE)(pCreateSurface->pSList[i].hKernelHandle);
  3267. }
  3268. }
  3269. LEAVE_DDRAW();
  3270. return DD_OK;
  3271. CreateErrorCleanup:
  3272. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  3273. {
  3274. pSurf = (PDDSURFACE)pCreateSurface->pSList[i].hKernelHandle;
  3275. if (pSurf != NULL)
  3276. {
  3277. FreeSurfaceObject(pSurf, TRUE);
  3278. // If we are reusing, then we need to keep the pSurf around
  3279. // for a retry
  3280. if (!pCreateSurface->bReUse)
  3281. {
  3282. MemFree(pSurf);
  3283. }
  3284. }
  3285. pCreateSurface->pSList[i].hKernelHandle = NULL;
  3286. }
  3287. LEAVE_DDRAW();
  3288. return MapLegacyResult(hr);
  3289. }
  3290. DWORD APIENTRY DdDestroySurface( PD3D8_DESTROYSURFACEDATA pDestroySurface )
  3291. {
  3292. DWORD i;
  3293. PDDSURFACE pSurf = (PDDSURFACE) pDestroySurface->hSurface;
  3294. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pDestroySurface->hDD;
  3295. PDEFERREDCREATE pDefCreate = pDevice->pDeferList;
  3296. ENTER_DDRAW();
  3297. FreeSurfaceObject(pSurf, TRUE);
  3298. if (pSurf != NULL)
  3299. {
  3300. // Free fpVidMem if we allocated it
  3301. if (pSurf->dwFlags & DDSURFACE_SYSMEMALLOCATED)
  3302. {
  3303. MemFree (pSurf->fpVidMem);
  3304. }
  3305. // Remove the surface from the linked list
  3306. if (pDevice->pSurfList == pSurf)
  3307. {
  3308. pDevice->pSurfList = pSurf->pNext;
  3309. if (pSurf->pNext != NULL)
  3310. {
  3311. pSurf->pNext->pPrevious = NULL;
  3312. }
  3313. }
  3314. else
  3315. {
  3316. if (pSurf->pNext != NULL)
  3317. {
  3318. pSurf->pNext->pPrevious = pSurf->pPrevious;
  3319. }
  3320. pSurf->pPrevious->pNext = pSurf->pNext;
  3321. }
  3322. MemFree(pSurf);
  3323. }
  3324. // We look in the defer list to see if any referenced surface
  3325. // is being destroyed. If this is the case, then we need to
  3326. // update the defer list and mark the surfaces as freed so
  3327. // that we don't try and resurrect destroyed surfaces. Although
  3328. // this appears slow, it is not too bad because a deferred list
  3329. // will be present only if a mode switch happened. In this case,
  3330. // it doesn't hurt if things are a little slow.
  3331. while (pDefCreate != NULL)
  3332. {
  3333. for (i = 0; i < pDefCreate->CreateData.dwSCnt; i++)
  3334. {
  3335. if (pSurf == (PDDSURFACE) pDefCreate->CreateData.pSList[i].hKernelHandle)
  3336. {
  3337. pDefCreate->CreateData.pSList[i].hKernelHandle = 0;
  3338. break;
  3339. }
  3340. }
  3341. pDefCreate = pDefCreate->pNext;
  3342. }
  3343. LEAVE_DDRAW();
  3344. return DD_OK;
  3345. }
  3346. DWORD APIENTRY DdGetScanLine( PD3D8_GETSCANLINEDATA pGetScanLine )
  3347. {
  3348. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pGetScanLine->hDD;
  3349. DWORD dwRet = DDHAL_DRIVER_HANDLED;
  3350. ENTER_BOTH();
  3351. if (CheckForDeviceLost(pDevice))
  3352. {
  3353. static int LostScanLine;
  3354. // When lost, we want to mix up the return values in case somebody
  3355. // calling us is waiting for these values to change
  3356. pGetScanLine->ddRVal = DD_OK;
  3357. if (LostScanLine == 0)
  3358. {
  3359. pGetScanLine->dwScanLine = 0;
  3360. pGetScanLine->bInVerticalBlank = TRUE;
  3361. }
  3362. else
  3363. {
  3364. pGetScanLine->dwScanLine = LostScanLine;
  3365. pGetScanLine->bInVerticalBlank = FALSE;
  3366. }
  3367. if ((LostScanLine += 10) > 100)
  3368. {
  3369. LostScanLine = 0;
  3370. }
  3371. }
  3372. else
  3373. {
  3374. LPDDHAL_GETSCANLINE gslhalfn;
  3375. LPDDHAL_GETSCANLINE gslfn;
  3376. gslfn = pDevice->pDD->lpLcl->lpDDCB->HALDD.GetScanLine;
  3377. gslhalfn = pDevice->pDD->lpLcl->lpDDCB->cbDDCallbacks.GetScanLine;
  3378. if( gslhalfn != NULL )
  3379. {
  3380. DDHAL_GETSCANLINEDATA gsld;
  3381. gsld.GetScanLine = gslhalfn;
  3382. gsld.lpDD = pDevice->pDD->lpLcl->lpGbl;
  3383. DOHALCALL( GetScanLine, gslfn, gsld, dwRet, FALSE );
  3384. if( dwRet == DDHAL_DRIVER_HANDLED )
  3385. {
  3386. pGetScanLine->dwScanLine = gsld.dwScanLine;
  3387. if (gsld.ddRVal == DDERR_VERTICALBLANKINPROGRESS)
  3388. {
  3389. gsld.ddRVal = DD_OK;
  3390. pGetScanLine->bInVerticalBlank = TRUE;
  3391. }
  3392. else
  3393. {
  3394. pGetScanLine->bInVerticalBlank = FALSE;
  3395. }
  3396. pGetScanLine->ddRVal = MapLegacyResult(gsld.ddRVal);
  3397. }
  3398. }
  3399. else
  3400. {
  3401. dwRet = DDHAL_DRIVER_NOTHANDLED;
  3402. }
  3403. }
  3404. LEAVE_BOTH();
  3405. return dwRet;
  3406. }
  3407. DWORD APIENTRY DdSetExclusiveMode( PD3D8_SETEXCLUSIVEMODEDATA pSetExclusiveMode )
  3408. {
  3409. DPF_ERR("DdSetExclusiveMode");
  3410. #if 0
  3411. LPDDRAWI_DIRECTDRAW_LCL lpDX7;
  3412. // Tell DDraw that we've grabbed exclusive mode
  3413. ENTER_DDRAW();
  3414. lpDX7 = ((LPDDRAWI_DIRECTDRAW_INT)(pSetExclusiveMode->lpDD->hDD))->lpLcl;
  3415. if( pSetExclusiveMode->dwEnterExcl )
  3416. {
  3417. lpDX7->dwLocalFlags |= DDRAWILCL_SETCOOPCALLED | DDRAWILCL_ISFULLSCREEN;
  3418. lpDX7->lpGbl->lpExclusiveOwner = lpDX7;
  3419. lpDX7->lpGbl->dwFlags |= DDRAWI_FULLSCREEN;
  3420. }
  3421. else
  3422. {
  3423. lpDX7->dwLocalFlags &= ~(DDRAWILCL_SETCOOPCALLED | DDRAWILCL_ISFULLSCREEN);
  3424. lpDX7->lpGbl->lpExclusiveOwner = NULL;
  3425. lpDX7->lpGbl->dwFlags &= ~DDRAWI_FULLSCREEN;
  3426. }
  3427. LEAVE_DDRAW();
  3428. #endif
  3429. pSetExclusiveMode->ddRVal = DD_OK;
  3430. return DDHAL_DRIVER_HANDLED;
  3431. }
  3432. DWORD APIENTRY DdFlipToGDISurface( PD3D8_FLIPTOGDISURFACEDATA pFlipToGDISurface )
  3433. {
  3434. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pFlipToGDISurface->hDD;
  3435. LPDDRAWI_DIRECTDRAW_INT lpDD = pDevice->pDD;
  3436. pFlipToGDISurface->ddRVal = MapLegacyResult(DD_FlipToGDISurface((LPDIRECTDRAW)lpDD));
  3437. return DDHAL_DRIVER_HANDLED;
  3438. }
  3439. DWORD APIENTRY DdSetColorkey( PD3D8_SETCOLORKEYDATA pSetColorkey)
  3440. {
  3441. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pSetColorkey->hDD;
  3442. PDDSURFACE pSurf = (PDDSURFACE) pSetColorkey->hSurface;
  3443. ENTER_BOTH();
  3444. pSetColorkey->ddRVal = DD_OK;
  3445. if (CheckForDeviceLost(pSetColorkey->hDD))
  3446. {
  3447. LEAVE_BOTH();
  3448. return DDHAL_DRIVER_HANDLED;
  3449. }
  3450. if (pSurf->Surface.pHeavy != NULL)
  3451. {
  3452. DDCOLORKEY DDColorKey;
  3453. // Since this will only be called with DX6 drivers, we know that
  3454. // it will only be heavyweight surfaces and we can use the legacy
  3455. // entry point.
  3456. DDColorKey.dwColorSpaceLowValue = pSetColorkey->ColorValue;
  3457. pSetColorkey->ddRVal = MapLegacyResult(DD_Surface_SetColorKey((LPDIRECTDRAWSURFACE)pSurf->Surface.pHeavy,
  3458. DDCKEY_SRCBLT,
  3459. &DDColorKey));
  3460. }
  3461. LEAVE_BOTH();
  3462. return DDHAL_DRIVER_HANDLED;
  3463. }
  3464. DWORD APIENTRY DdGetAvailDriverMemory( PD3D8_GETAVAILDRIVERMEMORYDATA pGetAvailDriverMemory )
  3465. {
  3466. DWORD dwTotal;
  3467. DWORD dwFree;
  3468. DDSCAPS ddscaps;
  3469. LPDDRAWI_DIRECTDRAW_INT pdrv_int = ((PDDDEVICEHANDLE)pGetAvailDriverMemory->hDD)->pDD;
  3470. ddscaps.dwCaps = DDSCAPS_TEXTURE;
  3471. pGetAvailDriverMemory->ddRVal = MapLegacyResult(DD_GetAvailableVidMem( (LPDIRECTDRAW)pdrv_int, &ddscaps, &dwTotal, &dwFree ));
  3472. pGetAvailDriverMemory->dwFree = dwFree;
  3473. return DDHAL_DRIVER_HANDLED;
  3474. }
  3475. HRESULT CalcDDSurfInfo( PDDCONTEXT pCtx, LPDDRAWI_DDRAWSURFACE_LCL pSLcl,
  3476. LPDDRAWI_DDRAWSURFACE_LCL pZLcl )
  3477. {
  3478. HRESULT ddrval;
  3479. DWORD dwWidth, dwHeight;
  3480. unsigned long m;
  3481. int s;
  3482. LPDDPIXELFORMAT pSPixFmt = NULL;
  3483. LPDDPIXELFORMAT pZPixFmt = NULL;
  3484. if( pSLcl == NULL ) return S_OK;
  3485. // Get info from the surface
  3486. dwWidth = pSLcl->lpGbl->wWidth;
  3487. dwHeight = pSLcl->lpGbl->wHeight;
  3488. GET_PIXEL_FORMAT( pSLcl, pSLcl->lpGbl, pSPixFmt );
  3489. if( ( pSPixFmt->dwFlags & ( DDPF_PALETTEINDEXED4 |
  3490. DDPF_PALETTEINDEXED8 ) ) == 0 )
  3491. {
  3492. // palettized pixfmts will not have valid RGB Bitmasks, so avoid
  3493. // computing this for them
  3494. pCtx->red_mask = pSPixFmt->dwRBitMask;
  3495. pCtx->green_mask = pSPixFmt->dwGBitMask;
  3496. pCtx->blue_mask = pSPixFmt->dwBBitMask;
  3497. if( (pCtx->red_mask == 0x0) || (pCtx->green_mask == 0x0) ||
  3498. (pCtx->blue_mask == 0x0) )
  3499. {
  3500. D3D_ERR("All the color masks in the Render target's pixel-format "
  3501. "must be non-zero");
  3502. return DDERR_INVALIDPIXELFORMAT;
  3503. }
  3504. // these are used by Clear
  3505. for( s = 0, m = pCtx->red_mask; !(m & 1); s++, m >>= 1 );
  3506. pCtx->red_shift = s;
  3507. pCtx->red_scale = 255 / (pCtx->red_mask >> s);
  3508. for( s = 0, m = pCtx->green_mask; !(m & 1); s++, m >>= 1 );
  3509. pCtx->green_shift = s;
  3510. pCtx->green_scale = 255 / (pCtx->green_mask >> s);
  3511. for( s = 0, m = pCtx->blue_mask; !(m & 1); s++, m >>= 1 );
  3512. pCtx->blue_shift = s;
  3513. pCtx->blue_scale = 255 / (pCtx->blue_mask >> s);
  3514. if( (pCtx->red_scale==0) || (pCtx->green_scale==0) ||
  3515. (pCtx->blue_scale==0) )
  3516. return DDERR_INVALIDPIXELFORMAT;
  3517. pCtx->bDDSTargetIsPalettized=FALSE;
  3518. }
  3519. else
  3520. {
  3521. pCtx->bDDSTargetIsPalettized=TRUE;
  3522. }
  3523. if( pZLcl )
  3524. {
  3525. // Get info from the surface
  3526. GET_PIXEL_FORMAT( pZLcl, pZLcl->lpGbl, pZPixFmt );
  3527. if( pZPixFmt->dwZBitMask!=0x0)
  3528. {
  3529. for(s = 0, m = pZPixFmt->dwZBitMask; !(m & 0x1); s++, m >>= 1);
  3530. pCtx->zmask_shift = s;
  3531. }
  3532. else
  3533. {
  3534. // if ZBitMask isn't being set, then Clear2 will never be used,
  3535. // so zbuf_shift/stencil_shift wont be needed anyway
  3536. pCtx->zmask_shift=0;
  3537. }
  3538. if( pZPixFmt->dwStencilBitMask != 0x0 )
  3539. {
  3540. for(s = 0, m = pZPixFmt->dwStencilBitMask; !(m & 0x1);
  3541. s++, m >>= 1) ;
  3542. pCtx->stencilmask_shift = s;
  3543. }
  3544. else
  3545. {
  3546. pCtx->stencilmask_shift=0;
  3547. }
  3548. }
  3549. return S_OK;
  3550. }
  3551. DWORD WINAPI D3dContextCreate(PD3D8_CONTEXTCREATEDATA pCreateContext)
  3552. {
  3553. D3DHAL_CONTEXTCREATEDATA data;
  3554. DWORD ret;
  3555. HRESULT hr = S_OK;
  3556. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pCreateContext->hDD;
  3557. LPDDRAWI_DIRECTDRAW_INT lpDD = pDevice->pDD;
  3558. PDDSURFACE lpDDSTarget = (PDDSURFACE)pCreateContext->hSurface;
  3559. PDDSURFACE lpDDSZBuffer = (PDDSURFACE)pCreateContext->hDDSZ;
  3560. PDDCONTEXT pContext;
  3561. ULONG cjBuffer = 0;
  3562. // Do the allocation first, since if it fails we don't have to do any real cleanup
  3563. ENTER_BOTH();
  3564. pDevice->pContext = NULL;
  3565. pContext = (PDDCONTEXT) MemAlloc(sizeof(DDCONTEXT));
  3566. if (pContext == NULL)
  3567. {
  3568. pCreateContext->ddrval = DDERR_OUTOFMEMORY;
  3569. LEAVE_BOTH();
  3570. return DDHAL_DRIVER_HANDLED;
  3571. }
  3572. // Now allocate the memory for the DPBuffer.
  3573. pContext->pDPBuffer = NULL;
  3574. cjBuffer = pCreateContext->cjBuffer;
  3575. if( cjBuffer == 0)
  3576. {
  3577. cjBuffer = DEF_PRIM_BUFFER_SIZE;
  3578. }
  3579. else if (cjBuffer < MIN_PRIM_BUFFER_SIZE ||
  3580. cjBuffer > MAX_PRIM_BUFFER_SIZE)
  3581. {
  3582. D3D_ERR("Illegal buffer size");
  3583. pCreateContext->ddrval = D3DERR_DRIVERINTERNALERROR;
  3584. MemFree( pContext );
  3585. LEAVE_BOTH();
  3586. return DDHAL_DRIVER_HANDLED;
  3587. }
  3588. pContext->pDPBuffer = (LPVOID)MemAlloc( cjBuffer );
  3589. if( pContext->pDPBuffer == NULL )
  3590. {
  3591. pCreateContext->ddrval = DDERR_OUTOFMEMORY;
  3592. MemFree( pContext );
  3593. LEAVE_BOTH();
  3594. return DDHAL_DRIVER_HANDLED;
  3595. }
  3596. pCreateContext->pvBuffer = (LPVOID)(((DWORD)pContext->pDPBuffer+31)&(~31));
  3597. pCreateContext->cjBuffer = cjBuffer;
  3598. // We need to check for a lost device before mucking around with the surfaces
  3599. if (CheckForDeviceLost(pDevice))
  3600. {
  3601. pContext->Context = 0;
  3602. pContext->pDevice = pDevice;
  3603. pDevice->pContext = pContext;
  3604. pCreateContext->dwhContext = (ULONG_PTR) pContext;
  3605. // Remember data required to create the context later
  3606. pContext->dwFlags = DDCONTEXT_DEFER;
  3607. pContext->dwTempContext = pCreateContext->dwhContext;
  3608. pContext->dwPID = pCreateContext->dwPID;
  3609. pContext->ddrval = pCreateContext->ddrval;
  3610. pCreateContext->ddrval = DD_OK;
  3611. LEAVE_BOTH();
  3612. return DDHAL_DRIVER_HANDLED;
  3613. }
  3614. // Calculate the surface info for Clear emulation if needed
  3615. hr = CalcDDSurfInfo( pContext,
  3616. (lpDDSTarget) ? lpDDSTarget->Surface.pHeavy->lpLcl
  3617. : NULL,
  3618. (lpDDSZBuffer) ? lpDDSZBuffer->Surface.pHeavy->lpLcl
  3619. : NULL );
  3620. if( FAILED( hr ) )
  3621. {
  3622. pCreateContext->ddrval = MapLegacyResult(hr);
  3623. MemFree(pContext->pDPBuffer);
  3624. pCreateContext->pvBuffer = NULL;
  3625. pCreateContext->cjBuffer = 0;
  3626. MemFree(pContext);
  3627. LEAVE_BOTH();
  3628. return DDHAL_DRIVER_HANDLED;
  3629. }
  3630. memset(&data, 0, sizeof(D3DHAL_CONTEXTCREATEDATA));
  3631. pDevice->pContext = NULL;
  3632. if (pDevice->DriverLevel >= 7)
  3633. {
  3634. if (lpDD)
  3635. data.lpDDLcl = lpDD->lpLcl;
  3636. else
  3637. data.lpDDLcl = NULL;
  3638. if (lpDDSTarget)
  3639. data.lpDDSLcl = lpDDSTarget->Surface.pHeavy->lpLcl;
  3640. else
  3641. data.lpDDSLcl = NULL;
  3642. if (lpDDSZBuffer)
  3643. data.lpDDSZLcl = lpDDSZBuffer->Surface.pHeavy->lpLcl;
  3644. else
  3645. data.lpDDSZLcl = NULL;
  3646. }
  3647. else
  3648. {
  3649. if (lpDD)
  3650. data.lpDDGbl = lpDD->lpLcl->lpGbl;
  3651. else
  3652. data.lpDDLcl = NULL;
  3653. if (lpDDSTarget)
  3654. data.lpDDS = (LPDIRECTDRAWSURFACE)lpDDSTarget->Surface.pHeavy;
  3655. else
  3656. data.lpDDS = NULL;
  3657. if (lpDDSZBuffer)
  3658. data.lpDDSZ = (LPDIRECTDRAWSURFACE)lpDDSZBuffer->Surface.pHeavy;
  3659. else
  3660. data.lpDDSZ = NULL;
  3661. }
  3662. // Hack Alert!! dwhContext is used to inform the driver which version
  3663. // of the D3D interface is calling it.
  3664. data.dwhContext = pCreateContext->dwhContext;
  3665. data.dwPID = pCreateContext->dwPID;
  3666. data.ddrval = pCreateContext->ddrval;
  3667. /* 0 for pre-DX5 devices.
  3668. * 1 for DX5 devices.
  3669. * 2 for DX6 devices.
  3670. * 3 for DX7 devices.
  3671. */
  3672. CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
  3673. pDevice,
  3674. lpDD->lpLcl->lpGbl->lpD3DHALCallbacks->ContextCreate,
  3675. &data);
  3676. if (ret != DDHAL_DRIVER_HANDLED || data.ddrval != DD_OK)
  3677. {
  3678. D3D_ERR( "Driver did not handle ContextCreate" );
  3679. MemFree(pContext->pDPBuffer);
  3680. pCreateContext->pvBuffer = NULL;
  3681. pCreateContext->cjBuffer = 0;
  3682. MemFree(pContext);
  3683. pCreateContext->dwhContext = 0;
  3684. pCreateContext->ddrval = D3DERR_DRIVERINTERNALERROR;
  3685. }
  3686. else
  3687. {
  3688. pContext->Context = data.dwhContext;
  3689. pContext->pDevice = pDevice;
  3690. pDevice->pContext = pContext;
  3691. pCreateContext->dwhContext = (ULONG_PTR) pContext;
  3692. pCreateContext->ddrval = data.ddrval;
  3693. }
  3694. LEAVE_BOTH();
  3695. return DDHAL_DRIVER_HANDLED;
  3696. }
  3697. HRESULT WINAPI D3dContextDestroy(PD3D8_CONTEXTDESTROYDATA pDestroyContext)
  3698. {
  3699. PDDCONTEXT pContext = (PDDCONTEXT) pDestroyContext->dwhContext;
  3700. ENTER_BOTH();
  3701. CheckForDeviceLost(pContext->pDevice);
  3702. pDestroyContext->ddrval = DD_OK;
  3703. if (pContext->Context)
  3704. {
  3705. D3DHAL_CONTEXTDESTROYDATA data;
  3706. DWORD ret;
  3707. DDSURFACE* pSurf;
  3708. // If there are any DX6 texture handles created w/ this context,
  3709. // we should destroy them now.
  3710. pSurf = pContext->pDevice->pSurfList;
  3711. while (pSurf != NULL)
  3712. {
  3713. if ((pSurf->dwFlags & DDSURFACE_DX6HANDLE) &&
  3714. (pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy != NULL))
  3715. {
  3716. D3DHAL_TEXTUREDESTROYDATA data;
  3717. DWORD ret;
  3718. data.dwhContext = (ULONG_PTR) pContext->Context;
  3719. data.dwHandle = pSurf->dwCookie;
  3720. CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
  3721. pSurf->pDevice,
  3722. pSurf->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy,
  3723. &data);
  3724. pSurf->dwFlags &= ~DDSURFACE_DX6HANDLE;
  3725. pSurf->dwCookie = 0;
  3726. }
  3727. pSurf = pSurf->pNext;
  3728. }
  3729. data.dwhContext = (ULONG_PTR) pContext->Context;
  3730. CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
  3731. pContext->pDevice,
  3732. pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->ContextDestroy,
  3733. &data);
  3734. pDestroyContext->ddrval = MapLegacyResult(data.ddrval);
  3735. }
  3736. if( pContext->pDPBuffer ) MemFree( pContext->pDPBuffer );
  3737. pContext->pDevice->pContext = NULL;
  3738. MemFree(pContext);
  3739. LEAVE_BOTH();
  3740. return DDHAL_DRIVER_HANDLED;
  3741. }
  3742. void BltFillRects( PDDCONTEXT pCtx, PDDSURFACE pDDS, DWORD count,
  3743. LPD3DRECT rect, D3DCOLOR dwFillColor)
  3744. {
  3745. HRESULT ddrval;
  3746. DDBLTFX bltfx;
  3747. RECT tr;
  3748. DWORD i;
  3749. DWORD r, g, b;
  3750. // Fill with background color
  3751. memset(&bltfx, 0, sizeof(bltfx));
  3752. bltfx.dwSize = sizeof(bltfx);
  3753. // unlike clear callback, which just takes pure 32-bit ARGB word and forces the driver to scale it for
  3754. // the pixelformat, here we need to compute the exact fill word, depending on surface's R,G,B bitmasks
  3755. if( pCtx->bDDSTargetIsPalettized )
  3756. {
  3757. // Palettized render targets are not supported
  3758. DDASSERT( TRUE );
  3759. }
  3760. else
  3761. {
  3762. DDASSERT((pCtx->red_scale!=0)&&(pCtx->green_scale!=0)&&(pCtx->blue_scale!=0));
  3763. r = RGB_GETRED(dwFillColor) / pCtx->red_scale;
  3764. g = RGB_GETGREEN(dwFillColor) / pCtx->green_scale;
  3765. b = RGB_GETBLUE(dwFillColor) / pCtx->blue_scale;
  3766. bltfx.dwFillColor = (r << pCtx->red_shift) | (g << pCtx->green_shift) |
  3767. (b << pCtx->blue_shift);
  3768. }
  3769. for (i = 0; i < count; i++,rect++)
  3770. {
  3771. tr.left = rect->x1;
  3772. tr.right = rect->x2;
  3773. tr.top = rect->y1;
  3774. tr.bottom = rect->y2;
  3775. do
  3776. {
  3777. ddrval = DD_Surface_Blt( (LPDIRECTDRAWSURFACE)pDDS->Surface.pHeavy,
  3778. &tr, NULL, NULL, DDBLT_COLORFILL, &bltfx);
  3779. } while (ddrval == DDERR_WASSTILLDRAWING);
  3780. }
  3781. }
  3782. void BltFillZRects( PDDCONTEXT pCtx, PDDSURFACE pDDSZ, unsigned long Zpixel,
  3783. DWORD count, LPD3DRECT rect, DWORD dwWriteMask)
  3784. {
  3785. HRESULT ddrval;
  3786. DDBLTFX bltfx;
  3787. DWORD i;
  3788. RECT tr;
  3789. DWORD dwExtraFlags=0;
  3790. memset(&bltfx, 0, sizeof(DDBLTFX));
  3791. bltfx.dwSize = sizeof(DDBLTFX);
  3792. bltfx.dwFillDepth = Zpixel;
  3793. // hack to pass DepthBlt WriteMask through ddraw/ddhel to blitlib
  3794. if( dwWriteMask != 0 )
  3795. {
  3796. bltfx.dwZDestConstBitDepth = dwWriteMask;
  3797. dwExtraFlags = DDBLT_DEPTHFILLWRITEMASK;
  3798. }
  3799. for(i=0; i<count ; i++, rect++)
  3800. {
  3801. tr.left = rect->x1;
  3802. tr.right = rect->x2;
  3803. tr.top = rect->y1;
  3804. tr.bottom = rect->y2;
  3805. do
  3806. {
  3807. ddrval = DD_Surface_Blt(
  3808. (LPDIRECTDRAWSURFACE)pDDSZ->Surface.pHeavy,
  3809. &tr, NULL, NULL,
  3810. DDBLT_DEPTHFILL |
  3811. dwExtraFlags, &bltfx );
  3812. } while (ddrval == DDERR_WASSTILLDRAWING);
  3813. }
  3814. }
  3815. DWORD WINAPI D3dClear( PD3D8_CLEAR2DATA pData )
  3816. {
  3817. PDDCONTEXT pContext = (PDDCONTEXT) pData->dwhContext;
  3818. LPDDRAWI_DIRECTDRAW_GBL pGbl = NULL;
  3819. DWORD ret = DDHAL_DRIVER_HANDLED;
  3820. DWORD dwFlags = pData->dwFlags;
  3821. BOOL bDoRGBClear = ((dwFlags & D3DCLEAR_TARGET)!=0);
  3822. BOOL bDoZClear = ((dwFlags & D3DCLEAR_ZBUFFER)!=0);
  3823. BOOL bDoStencilClear = ((dwFlags & D3DCLEAR_STENCIL)!=0);
  3824. D3DVALUE dvZ = pData->dvFillDepth;
  3825. PDDSURFACE pZBuffer = NULL;
  3826. LPDDRAWI_DDRAWSURFACE_GBL pZGbl = NULL;
  3827. LPDDRAWI_DDRAWSURFACE_LCL pZLcl = NULL;
  3828. LPDDPIXELFORMAT pZPixFmt = NULL;
  3829. pData->ddrval = S_OK;
  3830. ENTER_BOTH();
  3831. if (CheckForDeviceLost(pContext->pDevice))
  3832. {
  3833. LEAVE_BOTH();
  3834. return DDHAL_DRIVER_HANDLED;
  3835. }
  3836. pGbl = pContext->pDevice->pDD->lpLcl->lpGbl;
  3837. if( pGbl->lpD3DHALCallbacks3->Clear2 )
  3838. {
  3839. D3DHAL_CLEAR2DATA Clear2Data;
  3840. memcpy( &Clear2Data, pData, sizeof( Clear2Data ) );
  3841. Clear2Data.dwhContext = pContext->Context;
  3842. Clear2Data.ddrval = S_OK;
  3843. CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
  3844. pContext->pDevice,
  3845. pGbl->lpD3DHALCallbacks3->Clear2,
  3846. (D3DHAL_CLEAR2DATA *)&Clear2Data);
  3847. LEAVE_BOTH();
  3848. pData->ddrval = MapLegacyResult(Clear2Data.ddrval);
  3849. return ret;
  3850. }
  3851. if( pGbl->lpD3DGlobalDriverData->hwCaps.dpcTriCaps.dwRasterCaps &
  3852. D3DPRASTERCAPS_ZBUFFERLESSHSR )
  3853. {
  3854. if( bDoStencilClear )
  3855. {
  3856. D3D_ERR( "Invalid flag D3DCLEAR_STENCIL: this ZBUFFERLESSHSR "
  3857. "device doesn't support Stencil Clears");
  3858. pData->ddrval = D3DERR_DRIVERINTERNALERROR;
  3859. LEAVE_BOTH();
  3860. return DDHAL_DRIVER_NOTHANDLED;
  3861. }
  3862. if( bDoZClear )
  3863. {
  3864. if( !(pGbl->lpD3DHALCallbacks2->Clear) || (dvZ != 1.0f) )
  3865. {
  3866. D3D_WARN(3,"Ignoring D3DCLEAR_ZBUFFER since this "
  3867. "ZBUFFERLESSHSR device doesn't even support Clear "
  3868. "or Z!=1");
  3869. dwFlags &= ~(D3DCLEAR_ZBUFFER);
  3870. }
  3871. }
  3872. }
  3873. if( pData->hDDSZ )
  3874. {
  3875. pZBuffer = (PDDSURFACE)pData->hDDSZ;
  3876. pZLcl = pZBuffer->Surface.pHeavy->lpLcl;
  3877. pZGbl = pZLcl->lpGbl;
  3878. pZPixFmt = &pZGbl->ddpfSurface;
  3879. }
  3880. if( pGbl->lpD3DHALCallbacks2->Clear )
  3881. {
  3882. D3DHAL_CLEARDATA ClearData;
  3883. if( bDoZClear || bDoStencilClear )
  3884. {
  3885. if( (pZPixFmt != NULL) && //PowerVR need no Zbuffer
  3886. (DDPF_STENCILBUFFER & pZPixFmt->dwFlags))
  3887. {
  3888. // if surface has stencil bits, must verify either Clear2
  3889. // callback exists or we're using SW rasterizers
  3890. // (which require the special WriteMask DDHEL blt)
  3891. // This case should not be hit since we check right at the
  3892. // driver initialization time if the driver doesnt report
  3893. // Clear2 yet it supports stencils
  3894. if( pZLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY )
  3895. {
  3896. goto Emulateclear;
  3897. }
  3898. else
  3899. {
  3900. LEAVE_BOTH();
  3901. D3D_ERR( "Driver doesn't support StencilBuffer Clears");
  3902. pData->ddrval = D3DERR_DRIVERINTERNALERROR;
  3903. return DDHAL_DRIVER_NOTHANDLED;
  3904. }
  3905. }
  3906. // if Clear2 callback doesnt exist and it's a z-only surface and
  3907. // not doing zclear to non-max value then Clear2 is attempting to
  3908. // do no more than Clear could do, so it's safe to call Clear()
  3909. // instead of Clear2(), which will take advantage of older
  3910. // drivers that implement Clear but not Clear2
  3911. dwFlags &= ~D3DCLEAR_STENCIL; // Device cannot do stencil
  3912. }
  3913. if( bDoZClear && (dvZ != 1.0) )
  3914. {
  3915. ClearData.dwFlags = dwFlags & ~D3DCLEAR_ZBUFFER;
  3916. dwFlags = D3DCLEAR_ZBUFFER;
  3917. }
  3918. else
  3919. {
  3920. ClearData.dwFlags = dwFlags;
  3921. dwFlags = 0;
  3922. }
  3923. if (ClearData.dwFlags)
  3924. {
  3925. ClearData.dwhContext = pContext->Context;
  3926. // Here I will follow the ClearData.dwFillColor convention that
  3927. // color word is raw 32bit ARGB, unadjusted for surface bit depth
  3928. ClearData.dwFillColor = pData->dwFillColor;
  3929. // must clear to 0xffffffff because legacy drivers expect this
  3930. ClearData.dwFillDepth = 0xffffffff;
  3931. ClearData.lpRects = pData->lpRects;
  3932. ClearData.dwNumRects = pData->dwNumRects;
  3933. ClearData.ddrval = S_OK;
  3934. // if((err = CheckContextSurface(this)) != D3D_OK)
  3935. // {
  3936. // throw err;
  3937. // }
  3938. CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
  3939. pContext->pDevice,
  3940. pGbl->lpD3DHALCallbacks2->Clear,
  3941. (D3DHAL_CLEARDATA *)&ClearData);
  3942. pData->ddrval = MapLegacyResult(ClearData.ddrval);
  3943. LEAVE_BOTH();
  3944. return ret;
  3945. }
  3946. }
  3947. Emulateclear: // Fall back to Emulation using Blt
  3948. {
  3949. PDDSURFACE pTarget = (PDDSURFACE)pData->hDDS;
  3950. LPDDRAWI_DDRAWSURFACE_GBL pTargetGbl =
  3951. pTarget->Surface.pHeavy->lpLcl->lpGbl;
  3952. DWORD dwStencil = pData->dwFillStencil;
  3953. if(bDoRGBClear)
  3954. {
  3955. BltFillRects( pContext, (PDDSURFACE)pData->hDDS, pData->dwNumRects,
  3956. pData->lpRects, pData->dwFillColor );
  3957. //ok to not return possible errors from Blt?
  3958. }
  3959. if( (bDoZClear || bDoStencilClear) && NULL != pZPixFmt)
  3960. {
  3961. DWORD dwZbufferClearValue=0;
  3962. DWORD dwZbufferClearMask=0;
  3963. DDASSERT(pZPixFmt->dwZBufferBitDepth<=32);
  3964. DDASSERT(pZPixFmt->dwStencilBitDepth<32);
  3965. DDASSERT(pZPixFmt->dwZBitMask!=0x0);
  3966. DDASSERT((0xFFFFFFFF == (pZPixFmt->dwZBitMask |
  3967. pZPixFmt->dwStencilBitMask)) |
  3968. ((DWORD)((1<<pZPixFmt->dwZBufferBitDepth)-1) ==
  3969. (pZPixFmt->dwZBitMask | pZPixFmt->dwStencilBitMask)));
  3970. DDASSERT(0==(pZPixFmt->dwZBitMask & pZPixFmt->dwStencilBitMask));
  3971. if(bDoZClear)
  3972. {
  3973. dwZbufferClearMask = pZPixFmt->dwZBitMask;
  3974. // special case the common cases
  3975. if( dvZ==1.0f )
  3976. {
  3977. dwZbufferClearValue = pZPixFmt->dwZBitMask;
  3978. }
  3979. else if( dvZ > 0.0f )
  3980. {
  3981. dwZbufferClearValue =
  3982. ((DWORD)((dvZ*(pZPixFmt->dwZBitMask >>
  3983. pContext->zmask_shift)) + 0.5)) <<
  3984. pContext->zmask_shift;
  3985. }
  3986. }
  3987. if( bDoStencilClear )
  3988. {
  3989. DDASSERT(pZPixFmt->dwStencilBitMask!=0x0);
  3990. DDASSERT(pZPixFmt->dwFlags & DDPF_STENCILBUFFER);
  3991. dwZbufferClearMask |= pZPixFmt->dwStencilBitMask;
  3992. // special case the common case
  3993. if( dwStencil != 0 )
  3994. {
  3995. dwZbufferClearValue |= (dwStencil <<
  3996. pContext->stencilmask_shift) &
  3997. pZPixFmt->dwStencilBitMask;
  3998. }
  3999. }
  4000. if( dwZbufferClearMask == (pZPixFmt->dwStencilBitMask |
  4001. pZPixFmt->dwZBitMask) )
  4002. {
  4003. // do Stencil & Z Blt together, using regular DepthFill blt
  4004. // which will be faster than the writemask blt because its
  4005. // write-only, instead of read-modify-write
  4006. dwZbufferClearMask = 0;
  4007. }
  4008. BltFillZRects( pContext, (PDDSURFACE)pData->hDDSZ,
  4009. dwZbufferClearValue, pData->dwNumRects,
  4010. pData->lpRects, dwZbufferClearMask );
  4011. }
  4012. }
  4013. LEAVE_BOTH();
  4014. return ret;
  4015. }
  4016. DWORD WINAPI D3dSetRenderTarget( PD3D8_SETRENDERTARGETDATA pData )
  4017. {
  4018. PDDCONTEXT pContext = (PDDCONTEXT) pData->dwhContext;
  4019. LPDDRAWI_DIRECTDRAW_GBL pGbl = NULL;
  4020. DWORD ret = DDHAL_DRIVER_HANDLED;
  4021. ENTER_BOTH();
  4022. if (CheckForDeviceLost(pContext->pDevice))
  4023. {
  4024. LEAVE_BOTH();
  4025. pData->ddrval = DD_OK;
  4026. return DDHAL_DRIVER_HANDLED;
  4027. }
  4028. pGbl = pContext->pDevice->pDD->lpLcl->lpGbl;
  4029. if( pGbl->lpD3DHALCallbacks2->SetRenderTarget )
  4030. {
  4031. D3DHAL_SETRENDERTARGETDATA srtData;
  4032. // If creation of the render target was defered, create it now
  4033. if (pContext->dwFlags & DDCONTEXT_DEFER)
  4034. {
  4035. LPDDRAWI_DDRAWSURFACE_INT pTarget = NULL;
  4036. LPDDRAWI_DDRAWSURFACE_INT pZ = NULL;
  4037. HRESULT hr;
  4038. D3DHAL_CONTEXTCREATEDATA data;
  4039. DWORD ret;
  4040. if (pData->hDDS)
  4041. {
  4042. pTarget = ((PDDSURFACE)pData->hDDS)->Surface.pHeavy;
  4043. }
  4044. if (pData->hDDSZ)
  4045. {
  4046. pZ = ((PDDSURFACE)pData->hDDSZ)->Surface.pHeavy;
  4047. }
  4048. // Calculate the surface info for Clear emulation if needed
  4049. CalcDDSurfInfo(pContext,
  4050. (pTarget) ? pTarget->lpLcl : NULL,
  4051. (pZ) ? pZ->lpLcl : NULL);
  4052. memset(&data, 0, sizeof(D3DHAL_CONTEXTCREATEDATA));
  4053. if (pContext->pDevice->DriverLevel >= 7)
  4054. {
  4055. if (pContext->pDevice->pDD != NULL)
  4056. {
  4057. data.lpDDLcl = pContext->pDevice->pDD->lpLcl;
  4058. }
  4059. if (pTarget != NULL)
  4060. {
  4061. data.lpDDSLcl = pTarget->lpLcl;
  4062. }
  4063. else
  4064. {
  4065. data.lpDDSLcl = NULL;
  4066. }
  4067. if (pZ != NULL)
  4068. {
  4069. data.lpDDSZLcl = pZ->lpLcl;
  4070. }
  4071. else
  4072. {
  4073. data.lpDDSZLcl = NULL;
  4074. }
  4075. }
  4076. else
  4077. {
  4078. if (pContext->pDevice->pDD != NULL)
  4079. {
  4080. data.lpDDGbl = pContext->pDevice->pDD->lpLcl->lpGbl;
  4081. }
  4082. data.lpDDS = (LPDIRECTDRAWSURFACE)pTarget;
  4083. data.lpDDSZ = (LPDIRECTDRAWSURFACE) pZ;
  4084. }
  4085. // Hack Alert!! dwhContext is used to inform the driver which version
  4086. // of the D3D interface is calling it.
  4087. data.dwhContext = pContext->dwTempContext;
  4088. data.dwPID = pContext->dwPID;
  4089. data.ddrval = pContext->ddrval;
  4090. /* 0 for pre-DX5 devices.
  4091. * 1 for DX5 devices.
  4092. * 2 for DX6 devices.
  4093. * 3 for DX7 devices.
  4094. */
  4095. CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
  4096. pContext->pDevice,
  4097. pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->ContextCreate,
  4098. &data);
  4099. if (ret == DDHAL_DRIVER_HANDLED && data.ddrval == DD_OK)
  4100. {
  4101. pContext->Context = data.dwhContext;
  4102. }
  4103. pContext->dwFlags &= ~DDCONTEXT_DEFER;
  4104. }
  4105. pData->bNeedUpdate = FALSE;
  4106. memset( &srtData, 0, sizeof( srtData ) );
  4107. srtData.dwhContext = pContext->Context;
  4108. if( pData->hDDS )
  4109. srtData.lpDDS =
  4110. (LPDIRECTDRAWSURFACE)((PDDSURFACE)pData->hDDS)->Surface.pHeavy;
  4111. if( pData->hDDSZ )
  4112. srtData.lpDDSZ =
  4113. (LPDIRECTDRAWSURFACE)((PDDSURFACE)pData->hDDSZ)->Surface.pHeavy;
  4114. CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
  4115. pContext->pDevice,
  4116. pGbl->lpD3DHALCallbacks2->SetRenderTarget,
  4117. (D3DHAL_SETRENDERTARGETDATA *)&srtData );
  4118. pData->ddrval = MapLegacyResult(srtData.ddrval);
  4119. // If we need to create any defered texture handles, we will do so now
  4120. if (pContext->dwFlags & DDCONTEXT_DEFEREDTEXTUREHANDLES)
  4121. {
  4122. DDSURFACE* pSurf;
  4123. pContext->dwFlags &= ~ DDCONTEXT_DEFEREDTEXTUREHANDLES;
  4124. pSurf = pContext->pDevice->pSurfList;
  4125. while (pSurf != NULL)
  4126. {
  4127. if (pSurf->dwFlags & DDSURFACE_DEFERCREATETEXHANDLE)
  4128. {
  4129. D3DHAL_TEXTURECREATEDATA data;
  4130. DWORD ret;
  4131. memset(&data, 0, sizeof(D3DHAL_TEXTURECREATEDATA));
  4132. data.dwhContext = pContext->Context;
  4133. data.lpDDS = (LPDIRECTDRAWSURFACE) pSurf->Surface.pHeavy;
  4134. CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
  4135. pContext->pDevice,
  4136. pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureCreate,
  4137. &data);
  4138. pSurf->dwCookie = data.dwHandle;
  4139. pSurf->dwFlags |= DDSURFACE_DX6HANDLE;
  4140. pSurf->dwFlags &= ~DDSURFACE_DEFERCREATETEXHANDLE;
  4141. }
  4142. pSurf = pSurf->pNext;
  4143. }
  4144. }
  4145. LEAVE_BOTH();
  4146. return ret;
  4147. }
  4148. else
  4149. {
  4150. D3DHAL_CONTEXTCREATEDATA cdata;
  4151. D3DHAL_CONTEXTDESTROYDATA ddata;
  4152. DDSURFACE* pTemp;
  4153. // If we have allocated any texture handles, we need to free them now
  4154. pTemp = pContext->pDevice->pSurfList;
  4155. while (pTemp != NULL)
  4156. {
  4157. if ((pTemp->dwFlags & DDSURFACE_DX6HANDLE) &&
  4158. (pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy != NULL))
  4159. {
  4160. D3DHAL_TEXTUREDESTROYDATA data;
  4161. DWORD ret;
  4162. data.dwhContext = (ULONG_PTR) pContext->Context;
  4163. data.dwHandle = pTemp->dwCookie;
  4164. CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
  4165. pTemp->pDevice,
  4166. pTemp->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy,
  4167. &data);
  4168. }
  4169. pTemp = pTemp->pNext;
  4170. }
  4171. pData->bNeedUpdate = TRUE;
  4172. memset( &ddata, 0, sizeof(D3DHAL_CONTEXTDESTROYDATA) );
  4173. // Destroy Old Context
  4174. ddata.dwhContext = pContext->Context;
  4175. if (pContext->Context != 0)
  4176. {
  4177. CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
  4178. pContext->pDevice,
  4179. pGbl->lpD3DHALCallbacks->ContextDestroy,
  4180. &ddata );
  4181. if (ret != DDHAL_DRIVER_HANDLED || ddata.ddrval != DD_OK)
  4182. {
  4183. D3D_ERR( "SRT emulation, ContextDestroy failed." );
  4184. LEAVE_BOTH();
  4185. pData->ddrval = MapLegacyResult(ddata.ddrval);
  4186. return ret;
  4187. }
  4188. }
  4189. pContext->dwFlags &= ~(DDCONTEXT_DEFER | DDCONTEXT_DEFEREDTEXTUREHANDLES);
  4190. // Create a new Context
  4191. memset( &cdata, 0, sizeof(D3DHAL_CONTEXTCREATEDATA) );
  4192. cdata.lpDDGbl = pGbl;
  4193. if( pData->hDDS )
  4194. cdata.lpDDS =
  4195. (LPDIRECTDRAWSURFACE)((PDDSURFACE)pData->hDDS)->Surface.pHeavy;;
  4196. if( pData->hDDSZ )
  4197. cdata.lpDDSZ =
  4198. (LPDIRECTDRAWSURFACE)((PDDSURFACE)pData->hDDSZ)->Surface.pHeavy;
  4199. // Hack Alert!! dwhContext is used to inform the driver which version
  4200. // of the D3D interface is calling it.
  4201. // We don't want DX6 drivers to know that we are DX8 because
  4202. // we found at least one driver that starts behaving differently when
  4203. // it sees anything other than 3. (the driver was TNT2 and it turned
  4204. // off multitexturing thinking that anything other than 3 means DX5
  4205. // or below)
  4206. cdata.dwhContext = 3;
  4207. DDASSERT(pContext->pDevice->DriverLevel < 7); // should never get here for DX7 or above drivers
  4208. cdata.dwPID = GetCurrentProcessId();
  4209. CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
  4210. pContext->pDevice,
  4211. pGbl->lpD3DHALCallbacks->ContextCreate,
  4212. &cdata );
  4213. if (ret != DDHAL_DRIVER_HANDLED || cdata.ddrval != DD_OK)
  4214. {
  4215. D3D_ERR( "SRT emulation, ContextCreate failed" );
  4216. LEAVE_BOTH();
  4217. pData->dwhContext = 0;
  4218. pData->ddrval = MapLegacyResult(cdata.ddrval);
  4219. return ret;
  4220. }
  4221. pContext->Context = cdata.dwhContext;
  4222. pData->ddrval = MapLegacyResult(cdata.ddrval);
  4223. // Now we need to re-create any texture handles that we destroyed
  4224. if (pData->ddrval == DD_OK)
  4225. {
  4226. pTemp = pContext->pDevice->pSurfList;
  4227. while (pTemp != NULL)
  4228. {
  4229. if ((pTemp->dwFlags & DDSURFACE_DX6HANDLE) ||
  4230. (pTemp->dwFlags & DDSURFACE_DEFERCREATETEXHANDLE))
  4231. {
  4232. D3DHAL_TEXTURECREATEDATA data;
  4233. DWORD ret;
  4234. memset(&data, 0, sizeof(D3DHAL_TEXTURECREATEDATA));
  4235. data.dwhContext = pContext->Context;
  4236. data.lpDDS = (LPDIRECTDRAWSURFACE) pTemp->Surface.pHeavy;
  4237. CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
  4238. pTemp->pDevice,
  4239. pTemp->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureCreate,
  4240. &data);
  4241. pTemp->dwCookie = data.dwHandle;
  4242. pTemp->dwFlags |= DDSURFACE_DX6HANDLE;
  4243. pTemp->dwFlags &= ~DDSURFACE_DEFERCREATETEXHANDLE;
  4244. }
  4245. pTemp = pTemp->pNext;
  4246. }
  4247. }
  4248. }
  4249. LEAVE_BOTH();
  4250. return ret;
  4251. }
  4252. HRESULT WINAPI D3dContextDestroyAll(PD3D8_CONTEXTDESTROYALLDATA pDestroyAllContext)
  4253. {
  4254. return DDHAL_DRIVER_HANDLED;
  4255. }
  4256. HRESULT WINAPI D3dGetDriverState(PD3D8_GETDRIVERSTATEDATA pGetDriverState)
  4257. {
  4258. PDDCONTEXT pContext = (PDDCONTEXT) pGetDriverState->dwhContext;
  4259. DWORD dwRet = DDHAL_DRIVER_HANDLED;
  4260. ULONG_PTR pTemp;
  4261. pGetDriverState->ddRVal = D3DERR_DRIVERINTERNALERROR;
  4262. ENTER_BOTH();
  4263. if (!CheckForDeviceLost(pContext->pDevice))
  4264. {
  4265. pTemp = pGetDriverState->dwhContext;
  4266. pGetDriverState->dwhContext = (ULONG_PTR) pContext->Context;
  4267. CALL_D3DHAL_TAKEBUSY_NOWIN16(dwRet,
  4268. pContext->pDevice,
  4269. pContext->pDevice->pDD->lpLcl->lpGbl->lpDDCBtmp->HALDDMiscellaneous2.GetDriverState,
  4270. (LPDDHAL_GETDRIVERSTATEDATA)pGetDriverState);
  4271. pGetDriverState->dwhContext = pTemp;
  4272. pGetDriverState->ddRVal = MapLegacyResult(pGetDriverState->ddRVal);
  4273. }
  4274. LEAVE_BOTH();
  4275. return dwRet;
  4276. }
  4277. HRESULT WINAPI D3dValidateTextureStageState(PD3D8_VALIDATETEXTURESTAGESTATEDATA pValidate)
  4278. {
  4279. PDDCONTEXT pContext = (PDDCONTEXT) pValidate->dwhContext;
  4280. DWORD dwRet = DDHAL_DRIVER_HANDLED;
  4281. ULONG_PTR pTemp;
  4282. pValidate->ddrval = D3DERR_DEVICELOST;
  4283. pValidate->dwNumPasses = 0;
  4284. ENTER_BOTH();
  4285. if (!CheckForDeviceLost(pContext->pDevice))
  4286. {
  4287. pTemp = pValidate->dwhContext;
  4288. pValidate->dwhContext = (ULONG_PTR) pContext->Context;
  4289. CALL_D3DHAL_TAKEBUSY_NOWIN16(dwRet,
  4290. pContext->pDevice,
  4291. pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks3->ValidateTextureStageState,
  4292. (D3DHAL_VALIDATETEXTURESTAGESTATEDATA*) pValidate);
  4293. pValidate->dwhContext = pTemp;
  4294. }
  4295. LEAVE_BOTH();
  4296. return dwRet;
  4297. }
  4298. DWORD WINAPI D3dDrawPrimitives2(PD3D8_DRAWPRIMITIVES2DATA pdp2data)
  4299. {
  4300. D3DHAL_DRAWPRIMITIVES2DATA dp2data;
  4301. DWORD ret = 0;
  4302. PDDCONTEXT pContext = (PDDCONTEXT) pdp2data->dwhContext;
  4303. DDSURFACE* pSurfCommand;
  4304. LPDDRAWI_DDRAWSURFACE_INT pHeavyCommand;
  4305. DDSURFACE* pSurfVertex = NULL;
  4306. LPDDRAWI_DDRAWSURFACE_INT pHeavyVertex = NULL;
  4307. // Copy the data into our structure for easy access
  4308. memcpy (&dp2data, pdp2data, sizeof(dp2data));
  4309. // Start processing
  4310. ENTER_BOTH();
  4311. // Handle loss
  4312. if (CheckForDeviceLost(((PDDSURFACE)pdp2data->hDDCommands)->pDevice))
  4313. {
  4314. pdp2data->ddrval = DD_OK;
  4315. pdp2data->dwErrorOffset = 0;
  4316. // Need to set these values to their original
  4317. // state so that the FE doesn't get confused.
  4318. pdp2data->fpVidMem_CB = 0;
  4319. pdp2data->dwLinearSize_CB = 0;
  4320. pdp2data->fpVidMem_VB = 0;
  4321. pdp2data->dwLinearSize_VB = 0;
  4322. // May need to return a pointer here
  4323. if ((dp2data.dwFlags & D3DHALDP2_SWAPVERTEXBUFFER) &&
  4324. !(dp2data.dwFlags & D3DHALDP2_USERMEMVERTICES))
  4325. {
  4326. DDSURFACE* pVertex = (PDDSURFACE)pdp2data->hDDVertex;
  4327. if (pVertex->Pool == D3DPOOL_SYSTEMMEM)
  4328. {
  4329. if (pVertex->dwFlags & DDSURFACE_LIGHTWEIGHT)
  4330. {
  4331. pdp2data->fpVidMem_VB = pVertex->Surface.pLight->fpGblVidMem;
  4332. pdp2data->dwLinearSize_VB = pVertex->Surface.pLight->GblPitch;
  4333. }
  4334. else
  4335. {
  4336. pdp2data->fpVidMem_VB = pVertex->Surface.pHeavy->lpLcl->lpGbl->fpVidMem;
  4337. pdp2data->dwLinearSize_VB = pVertex->Surface.pHeavy->lpLcl->lpGbl->dwLinearSize;
  4338. }
  4339. }
  4340. else if (pVertex->dwFlags & DDSURFACE_HEAVYWEIGHT)
  4341. {
  4342. if ((pVertex->fpVidMem == NULL) ||
  4343. !(pVertex->dwFlags & DDSURFACE_SYSMEMALLOCATED))
  4344. {
  4345. pVertex->fpVidMem = (char*) MemAlloc(pVertex->Pitch);
  4346. if (pVertex->fpVidMem != NULL)
  4347. {
  4348. pVertex->dwFlags |= DDSURFACE_SYSMEMALLOCATED;
  4349. }
  4350. }
  4351. if (pVertex->dwFlags & DDSURFACE_SYSMEMALLOCATED)
  4352. {
  4353. pdp2data->fpVidMem_VB = (ULONG_PTR) pVertex->fpVidMem;
  4354. pdp2data->dwLinearSize_VB = pVertex->Pitch;
  4355. }
  4356. else
  4357. {
  4358. pdp2data->ddrval = DDERR_GENERIC;
  4359. }
  4360. }
  4361. }
  4362. LEAVE_BOTH();
  4363. return DDHAL_DRIVER_HANDLED;
  4364. }
  4365. pSurfCommand = (PDDSURFACE)pdp2data->hDDCommands;
  4366. pHeavyCommand = GetHeavyweightSurf(pSurfCommand);
  4367. if (pHeavyCommand != NULL)
  4368. {
  4369. dp2data.lpDDCommands = pHeavyCommand->lpLcl;
  4370. }
  4371. else
  4372. {
  4373. pdp2data->ddrval = DDERR_OUTOFMEMORY;
  4374. LEAVE_BOTH();
  4375. return DDHAL_DRIVER_HANDLED;
  4376. }
  4377. if (!(pdp2data->dwFlags & D3DHALDP2_USERMEMVERTICES))
  4378. {
  4379. pSurfVertex = (PDDSURFACE)pdp2data->hDDVertex;
  4380. pHeavyVertex = GetHeavyweightSurf(pSurfVertex);
  4381. dp2data.lpDDVertex = pHeavyVertex->lpLcl;
  4382. }
  4383. dp2data.dwhContext = ((PDDCONTEXT)dp2data.dwhContext)->Context;
  4384. if (((PDDSURFACE)pdp2data->hDDCommands)->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks3->DrawPrimitives2)
  4385. {
  4386. CALL_D3DHAL_TAKEBUSY_NOWIN16(
  4387. ret,
  4388. ((PDDSURFACE)pdp2data->hDDCommands)->pDevice,
  4389. ((PDDSURFACE)pdp2data->hDDCommands)->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks3->DrawPrimitives2,
  4390. &dp2data);
  4391. if ((ret == DDHAL_DRIVER_HANDLED) && (dp2data.ddrval != DD_OK)
  4392. && (DDERR_WASSTILLDRAWING != dp2data.ddrval))
  4393. {
  4394. ((PDDSURFACE)pdp2data->hDDCommands)->pDevice->bDP2Error = TRUE;
  4395. }
  4396. }
  4397. // If the call to the driver succeded, swap the buffers if needed and
  4398. // perform GetAliasVidmem
  4399. if (ret == DDHAL_DRIVER_HANDLED && (dp2data.ddrval == DD_OK))
  4400. {
  4401. pdp2data->fpVidMem_CB = 0;
  4402. pdp2data->dwLinearSize_CB = 0;
  4403. pdp2data->fpVidMem_VB = 0;
  4404. pdp2data->dwLinearSize_VB = 0;
  4405. if (dp2data.dwFlags & D3DHALDP2_SWAPCOMMANDBUFFER)
  4406. {
  4407. // CONSIDER: Implement VidMem command buffer
  4408. }
  4409. if ((dp2data.dwFlags & D3DHALDP2_SWAPVERTEXBUFFER) && !(dp2data.dwFlags & D3DHALDP2_USERMEMVERTICES))
  4410. {
  4411. FLATPTR paliasbits;
  4412. DWORD dwLinearSize = dp2data.lpDDVertex->lpGbl->dwLinearSize;
  4413. if (dp2data.dwFlags & D3DHALDP2_VIDMEMVERTEXBUF)
  4414. {
  4415. paliasbits = GetAliasedVidMem( dp2data.lpDDVertex->lpSurfMore->lpDD_lcl,
  4416. dp2data.lpDDVertex,
  4417. (FLATPTR) dp2data.lpDDVertex->lpGbl->fpVidMem );
  4418. if (paliasbits == 0)
  4419. {
  4420. D3D_ERR( "Could not get Aliased pointer for vid mem vertex buffer" );
  4421. // Since we can't use this pointer, set it's size to 0
  4422. // That way next time around we will try and allocate a new one
  4423. dwLinearSize = 0;
  4424. }
  4425. }
  4426. else
  4427. {
  4428. paliasbits = dp2data.lpDDVertex->lpGbl->fpVidMem;
  4429. }
  4430. pdp2data->fpVidMem_VB = paliasbits;
  4431. pdp2data->dwLinearSize_VB = dwLinearSize;
  4432. }
  4433. }
  4434. if ((pSurfCommand->dwFlags & DDSURFACE_LIGHTWEIGHT) &&
  4435. (pHeavyCommand != NULL))
  4436. {
  4437. UnmapLightweightSurface (pSurfCommand);
  4438. }
  4439. if ((pSurfVertex != NULL ) &&
  4440. (pSurfVertex->dwFlags & DDSURFACE_LIGHTWEIGHT) &&
  4441. (pHeavyVertex != NULL))
  4442. {
  4443. UnmapLightweightSurface (pSurfVertex);
  4444. }
  4445. pdp2data->ddrval = dp2data.ddrval;
  4446. pdp2data->dwErrorOffset = dp2data.dwErrorOffset;
  4447. LEAVE_BOTH();
  4448. // We don't map the errors to the new ones because the runtime still needs
  4449. // to deal with WASSTILLDRAWING, so it does the mapping instead of us.
  4450. return ret;
  4451. }
  4452. PALETTEINFO* GetPaletteInfo (PDDDEVICEHANDLE pDevice, DWORD PaletteID)
  4453. {
  4454. PALETTEINFO* pPaletteInfo;
  4455. HRESULT hr;
  4456. DWORD i;
  4457. // The palette IDs are app defined and can range from 0 - 65500. We don't
  4458. // want to always allocate a table with 65500 entries, and we don't want
  4459. // to walk a list on every palette call, so we will grow the table to the
  4460. // desired whenever we need to. This works well if we assume that most
  4461. // apps will start with low numbers and then work up.
  4462. if (PaletteID >= pDevice->NumPaletteHandleEntries)
  4463. {
  4464. // We need to grow the table
  4465. DWORD NewTableSize;
  4466. PALETTEINFO** pNewTable;
  4467. if (((DWORD)-1) - PaletteID <= EXTRA_PALETTE_PADDING)
  4468. {
  4469. NewTableSize = PaletteID + 1;
  4470. }
  4471. else
  4472. {
  4473. NewTableSize = PaletteID + EXTRA_PALETTE_PADDING + 1;
  4474. }
  4475. pNewTable = MemAlloc(NewTableSize * sizeof(PALETTEINFO*));
  4476. if (pNewTable == NULL)
  4477. {
  4478. return NULL;
  4479. }
  4480. if ((pDevice->pPaletteHandleTable) &&
  4481. (pDevice->NumPaletteHandleEntries > 0))
  4482. {
  4483. memcpy(pNewTable,
  4484. pDevice->pPaletteHandleTable,
  4485. pDevice->NumPaletteHandleEntries * sizeof(PALETTEINFO*));
  4486. MemFree(pDevice->pPaletteHandleTable);
  4487. }
  4488. pDevice->pPaletteHandleTable = pNewTable;
  4489. pDevice->NumPaletteHandleEntries = NewTableSize;
  4490. }
  4491. // If we already have info for this palette, we just return it now
  4492. if (pDevice->pPaletteHandleTable[PaletteID] != NULL)
  4493. {
  4494. return pDevice->pPaletteHandleTable[PaletteID];
  4495. }
  4496. // Otherwise, we allocate a structure and initialize it
  4497. pPaletteInfo = MemAlloc(sizeof(PALETTEINFO));
  4498. if (pPaletteInfo == NULL)
  4499. {
  4500. return NULL;
  4501. }
  4502. for (i = 0; i < 256; i++)
  4503. {
  4504. pPaletteInfo->ColorTable[i].peRed = (UCHAR) i;
  4505. pPaletteInfo->ColorTable[i].peGreen = (UCHAR) i;
  4506. pPaletteInfo->ColorTable[i].peBlue = (UCHAR) i;
  4507. pPaletteInfo->ColorTable[i].peFlags = (UCHAR) 0;
  4508. }
  4509. hr = DD_CreatePalette ((LPDIRECTDRAW) pDevice->pDD,
  4510. DDPCAPS_8BIT,
  4511. pPaletteInfo->ColorTable,
  4512. &pPaletteInfo->pDDPalette,
  4513. NULL);
  4514. if (hr != DD_OK)
  4515. {
  4516. MemFree(pPaletteInfo);
  4517. return NULL;
  4518. }
  4519. pDevice->pPaletteHandleTable[PaletteID] = pPaletteInfo;
  4520. return pPaletteInfo;
  4521. }
  4522. DWORD WINAPI DdSetPalette (PD3D8_SETPALETTEDATA pSetPalette)
  4523. {
  4524. PALETTEINFO* pPalette;
  4525. DDASSERT (((PDDDEVICEHANDLE)pSetPalette->hDD)->DriverLevel == 6);
  4526. ENTER_BOTH();
  4527. CheckForDeviceLost(pSetPalette->hDD);
  4528. pSetPalette->ddRVal = D3DERR_DRIVERINTERNALERROR;
  4529. pPalette = GetPaletteInfo (pSetPalette->hDD,
  4530. pSetPalette->Palette);
  4531. if (pPalette != NULL)
  4532. {
  4533. pSetPalette->ddRVal = DD_OK;
  4534. if ((((DDSURFACE*)pSetPalette->hSurface)->Surface.pHeavy != NULL) &&
  4535. (((DDSURFACE*)pSetPalette->hSurface)->Surface.pHeavy->lpLcl->lpDDPalette !=
  4536. (LPDDRAWI_DDRAWPALETTE_INT)pPalette->pDDPalette))
  4537. {
  4538. pSetPalette->ddRVal = MapLegacyResult(DD_Surface_SetPalette(
  4539. (LPDIRECTDRAWSURFACE)((DDSURFACE*)pSetPalette->hSurface)->Surface.pHeavy,
  4540. pPalette->pDDPalette));
  4541. }
  4542. }
  4543. LEAVE_BOTH();
  4544. return DDHAL_DRIVER_HANDLED;
  4545. }
  4546. DWORD WINAPI DdUpdatePalette (PD3D8_UPDATEPALETTEDATA pUpdatePalette)
  4547. {
  4548. PALETTEINFO* pPalette;
  4549. DDASSERT (((PDDDEVICEHANDLE)pUpdatePalette->hDD)->DriverLevel == 6);
  4550. ENTER_BOTH();
  4551. CheckForDeviceLost(pUpdatePalette->hDD);
  4552. pUpdatePalette->ddRVal = D3DERR_DRIVERINTERNALERROR;
  4553. pPalette = GetPaletteInfo (pUpdatePalette->hDD,
  4554. pUpdatePalette->Palette);
  4555. if (pPalette != NULL)
  4556. {
  4557. pUpdatePalette->ddRVal = MapLegacyResult(DD_Palette_SetEntries(
  4558. pPalette->pDDPalette,
  4559. 0,
  4560. 0,
  4561. 256,
  4562. pUpdatePalette->ColorTable));
  4563. }
  4564. LEAVE_BOTH();
  4565. return DDHAL_DRIVER_HANDLED;
  4566. }
  4567. DWORD WINAPI D3dSceneCapture (PD3D8_SCENECAPTUREDATA pData)
  4568. {
  4569. PDDCONTEXT pContext = (PDDCONTEXT) pData->dwhContext;
  4570. LPDDRAWI_DIRECTDRAW_GBL pGbl = NULL;
  4571. DWORD ret = DDHAL_DRIVER_HANDLED;
  4572. pData->ddrval = S_OK;
  4573. ENTER_BOTH();
  4574. if (CheckForDeviceLost(pContext->pDevice))
  4575. {
  4576. LEAVE_BOTH();
  4577. return DDHAL_DRIVER_HANDLED;
  4578. }
  4579. pGbl = pContext->pDevice->pDD->lpLcl->lpGbl;
  4580. if( pGbl->lpD3DHALCallbacks->SceneCapture )
  4581. {
  4582. D3DHAL_SCENECAPTUREDATA SceneCaptureData;
  4583. memcpy( &SceneCaptureData, pData, sizeof( SceneCaptureData ) );
  4584. SceneCaptureData.dwhContext = pContext->Context;
  4585. SceneCaptureData.ddrval = S_OK;
  4586. CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
  4587. pContext->pDevice,
  4588. pGbl->lpD3DHALCallbacks->SceneCapture,
  4589. (D3DHAL_SCENECAPTUREDATA *)&SceneCaptureData);
  4590. LEAVE_BOTH();
  4591. pData->ddrval = MapLegacyResult(SceneCaptureData.ddrval);
  4592. return ret;
  4593. }
  4594. LEAVE_BOTH();
  4595. return DDHAL_DRIVER_HANDLED;
  4596. }
  4597. //
  4598. // D3D8CreateDirectDrawObject
  4599. //
  4600. // Creates a DirectDraw object in DDRAW.DLL. By mainting a full representation of
  4601. // this object in DDRAW.DLL, it will automatically update the HAL info after mode
  4602. // changes, etc.
  4603. VOID APIENTRY D3D8CreateDirectDrawObject( LPGUID lpGuid,
  4604. char *szDeviceName,
  4605. HANDLE* phDD,
  4606. D3DDEVTYPE Type,
  4607. HINSTANCE* phLibrary,
  4608. VOID* pInitFunction)
  4609. {
  4610. HRESULT hr;
  4611. LPDIRECTDRAW lpDD1;
  4612. PD3D8GetSWInfo pfnHookCreate;
  4613. DDDEVICEHANDLE* pDeviceHandle;
  4614. HKEY hKey = (HKEY) NULL;
  4615. ENTER_DDRAW();
  4616. *phDD = NULL;
  4617. *phLibrary = NULL;
  4618. pDeviceHandle = (PDDDEVICEHANDLE) MemAlloc(sizeof(DDDEVICEHANDLE));
  4619. if (pDeviceHandle == NULL)
  4620. {
  4621. LEAVE_DDRAW();
  4622. return;
  4623. }
  4624. lstrcpy(pDeviceHandle->szDeviceName, szDeviceName);
  4625. pDeviceHandle->PID = GetCurrentProcessId();
  4626. hr = InternalDirectDrawCreate (NULL, &lpDD1, NULL,
  4627. DDRAWILCL_DIRECTDRAW7 | DDRAWILCL_DIRECTDRAW8, szDeviceName);
  4628. if( DD_OK == hr )
  4629. {
  4630. // Make it point to the DX7 vtbl. Do this rather than a QI since
  4631. // a QI for a DX7 object has some extra overhead.
  4632. lpDD1->lpVtbl = (LPVOID) &dd7Callbacks;
  4633. pDeviceHandle->pDD = (HANDLE) (LPDDRAWI_DIRECTDRAW_INT)lpDD1;
  4634. pDeviceHandle->DeviceType = Type;
  4635. if (Type == D3DDEVTYPE_REF)
  4636. {
  4637. // Load the refrast and let them take things over
  4638. *phLibrary = LoadLibrary (D3D8_REFRASTNAME);
  4639. pDeviceHandle->pSwDD = SwDDICreateDirectDraw();
  4640. if (pDeviceHandle->pSwDD != NULL)
  4641. {
  4642. *phDD = (HANDLE*) pDeviceHandle;
  4643. }
  4644. else
  4645. {
  4646. lpDD1->lpVtbl->Release(lpDD1);
  4647. }
  4648. }
  4649. else if (Type == D3DDEVTYPE_SW)
  4650. {
  4651. pDeviceHandle->pSwDD = SwDDICreateDirectDraw();
  4652. if (pDeviceHandle->pSwDD != NULL)
  4653. {
  4654. *phDD = (HANDLE*) pDeviceHandle;
  4655. pDeviceHandle->pSwInitFunction = pInitFunction;
  4656. }
  4657. }
  4658. else
  4659. {
  4660. *phDD = (HANDLE*) pDeviceHandle;
  4661. }
  4662. }
  4663. if (*phDD == NULL)
  4664. {
  4665. MemFree(pDeviceHandle);
  4666. }
  4667. else
  4668. {
  4669. pDeviceHandle->pLink = pDeviceList;
  4670. pDeviceList = pDeviceHandle;
  4671. }
  4672. LEAVE_DDRAW();
  4673. // See if they want to explicitly enable/disable lightweight surfaces
  4674. if ((*phDD != NULL) && (!RegOpenKey(HKEY_LOCAL_MACHINE, RESPATH_D3D, &hKey)))
  4675. {
  4676. DWORD type;
  4677. DWORD value;
  4678. DWORD cb = sizeof(value);
  4679. pDeviceHandle->ForceFlagsOn = 0;
  4680. pDeviceHandle->ForceFlagsOff = 0;
  4681. #ifdef DEBUG
  4682. if (!RegQueryValueEx(hKey, "ForceDriverFlagsOn", NULL, &type, (CONST LPBYTE)&value, &cb))
  4683. {
  4684. pDeviceHandle->ForceFlagsOn = value;
  4685. }
  4686. cb = sizeof(value);
  4687. #endif
  4688. if (!RegQueryValueEx(hKey, "ForceDriverFlagsOff", NULL, &type, (CONST LPBYTE)&value, &cb))
  4689. {
  4690. pDeviceHandle->ForceFlagsOff = value;
  4691. }
  4692. RegCloseKey(hKey);
  4693. }
  4694. }
  4695. //
  4696. // D3D8ReenableDirectDrawObject
  4697. //
  4698. // On Win9X, this function doesn't do anything, but we have it since Win2K
  4699. // requires it and keeping it keeps the code bases more similar between the
  4700. // two platforms.
  4701. BOOL WINAPI D3D8ReenableDirectDrawObject( HANDLE hDD, LPBOOL pbNewMode )
  4702. {
  4703. *pbNewMode = TRUE;
  4704. return TRUE;
  4705. }
  4706. BOOL
  4707. SWCursorForced()
  4708. {
  4709. if (0 != GetPrivateProfileInt("Display", "SwCursor", 0, "SYSTEM.INI"))
  4710. {
  4711. // ini setting always takes precedence
  4712. DPF(2,"System.ini says SwCursor is ON");
  4713. return TRUE;
  4714. }
  4715. else
  4716. {
  4717. HKEY key;
  4718. if (RegOpenKey(HKEY_CURRENT_CONFIG, "Display\\Settings", &key) == ERROR_SUCCESS)
  4719. {
  4720. char temp[10];
  4721. DWORD len = sizeof(temp);
  4722. DWORD type;
  4723. DWORD i;
  4724. if ((RegQueryValueEx(key, "SwCursor", NULL, (LPDWORD)&type,
  4725. (LPBYTE)(LPSTR)temp, (LPDWORD)&len) == ERROR_SUCCESS) &&
  4726. (type == REG_SZ))
  4727. {
  4728. for (i = 0; i < len; i++)
  4729. {
  4730. if ( 0 == temp[i] )
  4731. break;
  4732. if ( '0' != temp[i] )
  4733. {
  4734. RegCloseKey(key);
  4735. DPF(2,"Regkey SwCursor is ON");
  4736. return TRUE;
  4737. }
  4738. }
  4739. }
  4740. RegCloseKey(key);
  4741. }
  4742. }
  4743. return FALSE;
  4744. }
  4745. //
  4746. // D3D8QueryDirectDrawObject
  4747. //
  4748. // This gets all of the actual HAL info. It will typically be called twice,
  4749. // the first time to get the basic info (some of the input pointers will be
  4750. // NULL), and again to get all of the info.
  4751. BOOL WINAPI D3D8QueryDirectDrawObject (HANDLE hDD,
  4752. PD3D8_DRIVERCAPS pDriverCaps,
  4753. PD3D8_CALLBACKS pCallbacks,
  4754. char *pDeviceName,
  4755. HINSTANCE hLibrary,
  4756. D3D8_GLOBALDRIVERDATA* pGblDriverData,
  4757. D3DHAL_D3DEXTENDEDCAPS* pExtendedCaps,
  4758. LPDDSURFACEDESC pTextureFormats,
  4759. LPDDPIXELFORMAT pZStencilFormats,
  4760. UINT* pcTextureFormats,
  4761. UINT* pcZStencilFormats
  4762. )
  4763. {
  4764. LPDDRAWI_DIRECTDRAW_LCL pdrv_lcl;
  4765. LPDDRAWI_DIRECTDRAW_GBL pdrv;
  4766. DDSCAPSEX SurfCapsEx;
  4767. DWORD dwRet;
  4768. DWORD i;
  4769. HDC hdc;
  4770. D3DFORMAT* pTempZStencil;
  4771. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
  4772. DDHAL_GETDRIVERINFODATA GetDriverInfoData;
  4773. BOOL GotDX8Formats;
  4774. ENTER_DDRAW();
  4775. pdrv_lcl = pDevice->pDD->lpLcl;
  4776. pdrv = pdrv_lcl->lpGbl;
  4777. // Get all of the neccesary caps
  4778. memset(pDriverCaps, 0, sizeof(D3D8_DRIVERCAPS));
  4779. pDriverCaps->D3DCaps.Caps = pdrv->ddCaps.dwCaps;
  4780. pDriverCaps->D3DCaps.Caps2 = pdrv->ddCaps.dwCaps2;
  4781. pDriverCaps->D3DCaps.Caps3 = pdrv->ddCaps.dwSVCaps;
  4782. pDriverCaps->SVBCaps = pdrv->ddCaps.dwSVBCaps;
  4783. pDriverCaps->VSBCaps = pdrv->ddCaps.dwVSBCaps;
  4784. pDriverCaps->SVBCaps2 = pdrv->ddCaps.dwSVBCaps2;
  4785. SurfCapsEx.dwCaps2 = pdrv->ddsCapsMore.dwCaps2;
  4786. SurfCapsEx.dwCaps3 = pdrv->ddsCapsMore.dwCaps3;
  4787. SurfCapsEx.dwCaps4 = pdrv->ddsCapsMore.dwCaps4;
  4788. if (!IS_SOFTWARE_DRIVER(pDevice))
  4789. {
  4790. GotDX8Formats = FALSE;
  4791. // See if we can get the DX8 caps directly
  4792. if ((pdrv->dwFlags & DDRAWI_DRIVERINFO2) &&
  4793. (pdrv->pGetDriverInfo != NULL))
  4794. {
  4795. D3DCAPS8 caps8;
  4796. DD_GETDRIVERINFO2DATA* pgdi2;
  4797. memset(&caps8, 0, sizeof(caps8));
  4798. pgdi2 = (DD_GETDRIVERINFO2DATA*)&caps8;
  4799. // sizeof(DD_STEREOMODE)? The GUID for GetDriverInfo2 is shared with
  4800. // the stereo mode querying stuff. Therefore we need to pass down
  4801. // the structure size (and the expected data size) as
  4802. // sizeof(DD_STEREOMODE) even though we actually have a buffer (and
  4803. // expect a size of sizeof(D3DCAPS8).
  4804. pgdi2->dwReserved = sizeof(D3DCAPS8);
  4805. pgdi2->dwMagic = D3DGDI2_MAGIC;
  4806. pgdi2->dwType = D3DGDI2_TYPE_GETD3DCAPS8;
  4807. pgdi2->dwExpectedSize = sizeof(D3DCAPS8);
  4808. memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
  4809. GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
  4810. GetDriverInfoData.guidInfo = GUID_GetDriverInfo2;
  4811. GetDriverInfoData.lpvData = &caps8;
  4812. GetDriverInfoData.dwExpectedSize = sizeof(D3DCAPS8);
  4813. // Pass a context variable so that the driver
  4814. // knows which instance of itself to use
  4815. // w.r.t. this function. These are different
  4816. // values on Win95 and NT.
  4817. GetDriverInfoData.dwContext = pdrv->dwReserved3;
  4818. if ((pdrv->pGetDriverInfo(&GetDriverInfoData) == DDHAL_DRIVER_HANDLED) &&
  4819. (GetDriverInfoData.ddRVal == DD_OK ))
  4820. {
  4821. // Looks like we got D3DCAPS8 back from the driver. Verify by means
  4822. // of the dwActualSize field in GetDriverInfoData.
  4823. if (sizeof(D3DCAPS8) != GetDriverInfoData.dwActualSize)
  4824. {
  4825. DPF(0, "Driver returned an data structure of incorrect size (!= sizeof(D3DCAPS8))");
  4826. LEAVE_DDRAW();
  4827. return(FALSE);
  4828. }
  4829. // All went well. Copy the caps data across
  4830. memcpy(&pDriverCaps->D3DCaps, &caps8, sizeof(caps8));
  4831. // Display drivers can all render windowed
  4832. if (pdrv->ddCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED)
  4833. {
  4834. pDriverCaps->D3DCaps.Caps2 |= DDCAPS2_CANRENDERWINDOWED;
  4835. }
  4836. // Set the flag indicating that the DDI successfully reported DX8
  4837. // style caps
  4838. pDriverCaps->dwFlags |= DDIFLAG_D3DCAPS8;
  4839. }
  4840. }
  4841. // If this driver supports the DX8 DDI then use the new surface format reporting
  4842. // mechanism rather than the texture formats reported in the global driver data
  4843. if (pDriverCaps->dwFlags & DDIFLAG_D3DCAPS8)
  4844. {
  4845. DD_GETDRIVERINFO2DATA* pgdi2;
  4846. DD_GETFORMATCOUNTDATA gfcd;
  4847. DD_GETFORMATDATA gfd;
  4848. // If DDIFLAG_D3DCAPS8 got set we have a driver info 2 support
  4849. DDASSERT(pdrv->dwFlags & DDRAWI_DRIVERINFO2);
  4850. DDASSERT(pdrv->pGetDriverInfo != NULL);
  4851. // Step 1: Get the number of supported formats
  4852. // Please see the description comments above for a description of why the
  4853. // reserved field is set to sizeof(DD_STEREOMODE)
  4854. memset(&gfcd, 0, sizeof(gfcd));
  4855. gfcd.gdi2.dwReserved = sizeof(DD_GETFORMATCOUNTDATA);
  4856. gfcd.gdi2.dwMagic = D3DGDI2_MAGIC;
  4857. gfcd.gdi2.dwType = D3DGDI2_TYPE_GETFORMATCOUNT;
  4858. gfcd.gdi2.dwExpectedSize = sizeof(DD_GETFORMATCOUNTDATA);
  4859. #if DBG
  4860. // Ensure the driver actually sets the format count if it succeeds this call
  4861. gfcd.dwFormatCount = BOGUS_FIELD_VALUE;
  4862. #endif // DBG
  4863. memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
  4864. GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
  4865. GetDriverInfoData.guidInfo = GUID_GetDriverInfo2;
  4866. GetDriverInfoData.lpvData = &gfcd;
  4867. GetDriverInfoData.dwExpectedSize = sizeof(DD_GETFORMATCOUNTDATA);
  4868. GetDriverInfoData.dwContext = pdrv->dwReserved3;
  4869. if ((pdrv->pGetDriverInfo(&GetDriverInfoData) == DDHAL_DRIVER_HANDLED) &&
  4870. (GetDriverInfoData.ddRVal == DD_OK ))
  4871. {
  4872. // Looks like we got a DD_GETFORMATCOUNTDATA back from the driver. Verify by means
  4873. // of the dwActualSize field in GetDriverInfoData.
  4874. if (sizeof(DD_GETFORMATCOUNTDATA) != GetDriverInfoData.dwActualSize)
  4875. {
  4876. DPF(0, "Driver returned an data structure of incorrect size (!= sizeof(DD_GETFORMATCOUNTDATA))");
  4877. LEAVE_DDRAW();
  4878. return(FALSE);
  4879. }
  4880. #ifdef DBG
  4881. if (BOGUS_FIELD_VALUE == gfcd.dwFormatCount)
  4882. {
  4883. DPF_ERR( "Driver succeeded GETFORMATCOUNT request but didn't set dwFormatCount" );
  4884. LEAVE_DDRAW();
  4885. return(FALSE);
  4886. }
  4887. #endif // DBG
  4888. // All went well. Replace the number of supported texture formats the driver
  4889. // reported to us with this new number. We don't use the legacy texture format
  4890. // list if this new mechanism is supported
  4891. *pcTextureFormats = gfcd.dwFormatCount;
  4892. // Flag the fact that we got DX8 style formats from the driver.
  4893. GotDX8Formats = TRUE;
  4894. // Step2: Query for each of the surface formats in turn.
  4895. // We only do this if the caller requested that we do by means of a non-NULL
  4896. // texture format buffer
  4897. if (NULL != pTextureFormats)
  4898. {
  4899. DWORD c;
  4900. DDSURFACEDESC* pOutFormat;
  4901. // For simplicities sake we ask for a single format at a time. Not exactly
  4902. // high-performance but this should not matter at this stage of the code.
  4903. pOutFormat = pTextureFormats;
  4904. for (c = 0; c < (*pcTextureFormats); ++c)
  4905. {
  4906. // We reinitialize the entire request each time. We could probably
  4907. // optimize this but it doesn't seem worth it.
  4908. memset(&gfd, 0, sizeof(DD_GETFORMATDATA));
  4909. gfd.gdi2.dwReserved = sizeof(DD_GETFORMATDATA);
  4910. gfd.gdi2.dwMagic = D3DGDI2_MAGIC;
  4911. gfd.gdi2.dwType = D3DGDI2_TYPE_GETFORMAT;
  4912. gfd.gdi2.dwExpectedSize = sizeof(DD_GETFORMATDATA);
  4913. gfd.dwFormatIndex = c;
  4914. #if DBG
  4915. // Ensure the driver actually sets the format count if it succeeds this call
  4916. gfd.format.dwSize = BOGUS_FIELD_VALUE;
  4917. #endif // DBG
  4918. memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
  4919. GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
  4920. GetDriverInfoData.guidInfo = GUID_GetDriverInfo2;
  4921. GetDriverInfoData.lpvData = &gfd;
  4922. GetDriverInfoData.dwExpectedSize = sizeof(DD_GETFORMATDATA);
  4923. GetDriverInfoData.dwContext = pdrv->dwReserved3;
  4924. if ((pdrv->pGetDriverInfo(&GetDriverInfoData) == DDHAL_DRIVER_HANDLED) &&
  4925. (GetDriverInfoData.ddRVal == DD_OK ))
  4926. {
  4927. // Looks like we got a DD_GETFORMATDATA back from the driver. Verify by means
  4928. // of the dwActualSize field in GetDriverInfoData.
  4929. if (sizeof(DD_GETFORMATDATA) != GetDriverInfoData.dwActualSize)
  4930. {
  4931. DPF(0, "Driver returned an data structure of incorrect size (!= sizeof(DD_GETFORMATDATA))");
  4932. LEAVE_DDRAW();
  4933. return(FALSE);
  4934. }
  4935. DDASSERT(c == gfd.dwFormatIndex);
  4936. #ifdef DBG
  4937. if (BOGUS_FIELD_VALUE == gfd.format.dwSize)
  4938. {
  4939. DPF_ERR( "Driver succeeded GETFORMAT request but didn't set format" );
  4940. LEAVE_DDRAW();
  4941. return(FALSE);
  4942. }
  4943. #endif // DBG
  4944. // Looks like all went well so initialize the surface description
  4945. // part of the output format and copy the pixel format we got from
  4946. // the driver across
  4947. memset(pOutFormat, 0, sizeof(DDSURFACEDESC));
  4948. pOutFormat->dwSize = sizeof(DDSURFACEDESC);
  4949. pOutFormat->dwFlags = DDSD_PIXELFORMAT;
  4950. memcpy(&pOutFormat->ddpfPixelFormat, &(gfd.format), sizeof(DDPIXELFORMAT));
  4951. ++pOutFormat;
  4952. }
  4953. }
  4954. }
  4955. }
  4956. else
  4957. {
  4958. DPF(0, "Driver claims DX8 but fails call to GETFORMATCOUNT" );
  4959. DPF(0, "DX7 texture format list will be used but this will change soon" );
  4960. DPF(0, "Fix driver to support DX8 style surface format reporting now" );
  4961. }
  4962. }
  4963. // The driver does not support the DX8 DDI so simply use the existing DX7
  4964. // style texture format list.
  4965. if (pdrv->lpD3DGlobalDriverData != NULL)
  4966. {
  4967. // Wackiness to get around type checking
  4968. *pGblDriverData = *(D3D8_GLOBALDRIVERDATA*) pdrv_lcl->lpGbl->lpD3DGlobalDriverData;
  4969. // If we alreay have DX8 style formats from the driver don't bother using the DX7
  4970. // style texture format list
  4971. if (!GotDX8Formats)
  4972. {
  4973. *pcTextureFormats = pdrv_lcl->lpGbl->lpD3DGlobalDriverData->dwNumTextureFormats;
  4974. if (pTextureFormats != NULL)
  4975. {
  4976. memcpy(
  4977. pTextureFormats,
  4978. pdrv_lcl->lpGbl->lpD3DGlobalDriverData->lpTextureFormats,
  4979. pdrv_lcl->lpGbl->lpD3DGlobalDriverData->dwNumTextureFormats*sizeof(*pTextureFormats));
  4980. }
  4981. }
  4982. // Get the D3D extended caps
  4983. if (pdrv->lpD3DExtendedCaps)
  4984. {
  4985. *pExtendedCaps = *(pdrv->lpD3DExtendedCaps);
  4986. }
  4987. }
  4988. else
  4989. {
  4990. // If we alreay have DX8 style formats from the driver don't bother using the DX7
  4991. // style texture format list
  4992. if (!GotDX8Formats)
  4993. {
  4994. *pcTextureFormats = 0;
  4995. }
  4996. }
  4997. // Get the supported Z formats. We only do this if we are not using a
  4998. // software driver
  4999. *pcZStencilFormats = pdrv->dwNumZPixelFormats;
  5000. if (pdrv->dwNumZPixelFormats > 0)
  5001. {
  5002. if (pZStencilFormats)
  5003. {
  5004. memcpy(pZStencilFormats,
  5005. pdrv->lpZPixelFormats,
  5006. pdrv->dwNumZPixelFormats * sizeof( *pZStencilFormats ));
  5007. }
  5008. }
  5009. else
  5010. {
  5011. if (pGblDriverData->hwCaps.dwDeviceZBufferBitDepth & DDBD_16)
  5012. {
  5013. (*pcZStencilFormats)++;
  5014. if (pZStencilFormats)
  5015. {
  5016. pZStencilFormats->dwSize = sizeof(DDPIXELFORMAT);
  5017. pZStencilFormats->dwFlags = DDPF_ZBUFFER;
  5018. pZStencilFormats->dwZBufferBitDepth = 16;
  5019. pZStencilFormats->dwStencilBitDepth = 0;
  5020. pZStencilFormats->dwZBitMask = 0xffff;
  5021. pZStencilFormats->dwStencilBitMask = 0x0000;
  5022. pZStencilFormats++;
  5023. }
  5024. }
  5025. if (pGblDriverData->hwCaps.dwDeviceZBufferBitDepth & DDBD_32)
  5026. {
  5027. (*pcZStencilFormats)++;
  5028. if (pZStencilFormats)
  5029. {
  5030. pZStencilFormats->dwSize = sizeof(DDPIXELFORMAT);
  5031. pZStencilFormats->dwFlags = DDPF_ZBUFFER;
  5032. pZStencilFormats->dwZBufferBitDepth = 32;
  5033. pZStencilFormats->dwStencilBitDepth = 0;
  5034. pZStencilFormats->dwZBitMask = 0xffffffff;
  5035. pZStencilFormats->dwStencilBitMask = 0x00000000;
  5036. pZStencilFormats++;
  5037. }
  5038. }
  5039. }
  5040. }
  5041. // Get info about the current mode
  5042. pDriverCaps->DisplayWidth = pdrv->vmiData.dwDisplayWidth;
  5043. pDriverCaps->DisplayHeight = pdrv->vmiData.dwDisplayHeight;
  5044. pDriverCaps->DisplayFrequency = pdrv->dwMonitorFrequency;
  5045. switch (pdrv->vmiData.ddpfDisplay.dwRGBBitCount)
  5046. {
  5047. case 8:
  5048. pDriverCaps->DisplayFormatWithAlpha = D3DFMT_P8;
  5049. pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_P8;
  5050. break;
  5051. case 15:
  5052. case 16:
  5053. if (pdrv->vmiData.ddpfDisplay.dwGBitMask == 0x7e0)
  5054. {
  5055. pDriverCaps->DisplayFormatWithAlpha = D3DFMT_R5G6B5;
  5056. pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_R5G6B5;
  5057. }
  5058. else
  5059. {
  5060. pDriverCaps->DisplayFormatWithAlpha = D3DFMT_X1R5G5B5;
  5061. pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_X1R5G5B5;
  5062. if (pdrv->vmiData.ddpfDisplay.dwFlags & DDPF_ALPHAPIXELS)
  5063. {
  5064. pDriverCaps->DisplayFormatWithAlpha = D3DFMT_A1R5G5B5;
  5065. }
  5066. //pdrv->vmiData.ddpfDisplay.dwRGBAlphaBitMask = 0;
  5067. //pdrv->vmiData.ddpfDisplay.dwFlags &= ~DDPF_ALPHAPIXELS;
  5068. }
  5069. break;
  5070. case 24:
  5071. pDriverCaps->DisplayFormatWithAlpha = D3DFMT_R8G8B8;
  5072. pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_R8G8B8;
  5073. break;
  5074. case 32:
  5075. pDriverCaps->DisplayFormatWithAlpha = D3DFMT_X8R8G8B8;
  5076. pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_X8R8G8B8;
  5077. if (pdrv->vmiData.ddpfDisplay.dwFlags & DDPF_ALPHAPIXELS)
  5078. {
  5079. pDriverCaps->DisplayFormatWithAlpha = D3DFMT_A8R8G8B8;
  5080. }
  5081. //pdrv->vmiData.ddpfDisplay.dwRGBAlphaBitMask = 0;
  5082. //pdrv->vmiData.ddpfDisplay.dwFlags &= ~DDPF_ALPHAPIXELS;
  5083. break;
  5084. default:
  5085. pDriverCaps->DisplayFormatWithAlpha = D3DFMT_UNKNOWN;
  5086. pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_UNKNOWN;
  5087. break;
  5088. }
  5089. pDevice->DisplayFormatWithAlpha = pDriverCaps->DisplayFormatWithAlpha;
  5090. pDevice->DisplayFormatWithoutAlpha = pDriverCaps->DisplayFormatWithoutAlpha;
  5091. // Fill in the D3D8 Callback table
  5092. RtlZeroMemory(pCallbacks, sizeof(*pCallbacks));
  5093. pCallbacks->CreateSurface = DdCreateSurface;
  5094. pCallbacks->DestroySurface = DdDestroySurface;
  5095. pCallbacks->Lock = DdLock;
  5096. pCallbacks->Unlock = DdUnlock;
  5097. pCallbacks->Blt = DdBlt;
  5098. pCallbacks->GetScanLine = DdGetScanLine;
  5099. pCallbacks->Flip = DdFlip;
  5100. pCallbacks->WaitForVerticalBlank = DdWaitForVerticalBlank;
  5101. pCallbacks->GetBltStatus = DdGetBltStatus;
  5102. pCallbacks->GetFlipStatus = DdGetFlipStatus;
  5103. pCallbacks->SetMode = DdSetMode;
  5104. pCallbacks->FlipToGDISurface = DdFlipToGDISurface;
  5105. pCallbacks->SetExclusiveMode = DdSetExclusiveMode;
  5106. pCallbacks->GetAvailDriverMemory = DdGetAvailDriverMemory;
  5107. pCallbacks->Clear2 = D3dClear;
  5108. pCallbacks->SetRenderTarget = D3dSetRenderTarget;
  5109. pCallbacks->SetColorkey = DdSetColorkey;
  5110. pCallbacks->SetPalette = DdSetPalette;
  5111. pCallbacks->UpdatePalette = DdUpdatePalette;
  5112. pCallbacks->SceneCapture = D3dSceneCapture;
  5113. if ((pdrv->lpD3DHALCallbacks != NULL) &&
  5114. (pdrv->lpD3DHALCallbacks->ContextCreate != NULL))
  5115. {
  5116. pCallbacks->CreateContext = D3dContextCreate;
  5117. }
  5118. if ((pdrv->lpD3DHALCallbacks != NULL) &&
  5119. (pdrv->lpD3DHALCallbacks->ContextDestroy != NULL))
  5120. {
  5121. pCallbacks->ContextDestroy = D3dContextDestroy;
  5122. }
  5123. if ((pdrv->lpD3DHALCallbacks != NULL) &&
  5124. (pdrv->lpD3DHALCallbacks->ContextDestroyAll != NULL))
  5125. {
  5126. pCallbacks->ContextDestroyAll = D3dContextDestroyAll;
  5127. }
  5128. if (pdrv->lpDDCBtmp->HALDDMiscellaneous2.GetDriverState != NULL)
  5129. {
  5130. pCallbacks->GetDriverState = D3dGetDriverState;
  5131. }
  5132. if ((pdrv->lpD3DHALCallbacks3 != NULL) &&
  5133. (pdrv->lpD3DHALCallbacks3->ValidateTextureStageState != NULL))
  5134. {
  5135. pCallbacks->ValidateTextureStageState = D3dValidateTextureStageState;
  5136. }
  5137. if ((pdrv->lpD3DHALCallbacks3 != NULL) &&
  5138. (pdrv->lpD3DHALCallbacks3->DrawPrimitives2 != NULL))
  5139. {
  5140. pCallbacks->DrawPrimitives2 = D3dDrawPrimitives2;
  5141. }
  5142. // If Refrast or the HEL has a hook, call it to let it change whatever it wants
  5143. if (IS_SOFTWARE_DRIVER(pDevice))
  5144. {
  5145. *pcZStencilFormats = 0;
  5146. SwDDIMungeCaps (
  5147. hLibrary,
  5148. hDD,
  5149. pDriverCaps,
  5150. pCallbacks,
  5151. pTextureFormats,
  5152. pcTextureFormats,
  5153. pDevice->pSwInitFunction
  5154. );
  5155. }
  5156. // Now we need to determine what level of DX support the driver supports
  5157. pDevice->DriverLevel = 0;
  5158. if (pDriverCaps->D3DCaps.MaxStreams != 0)
  5159. {
  5160. pDevice->DriverLevel = 8;
  5161. }
  5162. else if (pCallbacks->GetDriverState != 0)
  5163. {
  5164. pDevice->DriverLevel = 7;
  5165. }
  5166. else if (pCallbacks->DrawPrimitives2 != 0)
  5167. {
  5168. pDevice->DriverLevel = 6;
  5169. if (pDevice->pDefaultPalette == NULL)
  5170. {
  5171. PALETTEENTRY ColorTable[256];
  5172. int i;
  5173. for (i = 0; i < 256; i++)
  5174. {
  5175. ColorTable[i].peRed = (UCHAR) i;
  5176. ColorTable[i].peGreen = (UCHAR) i;
  5177. ColorTable[i].peBlue = (UCHAR) i;
  5178. }
  5179. DPF_MUTE();
  5180. DD_CreatePalette ((LPDIRECTDRAW) pDevice->pDD,
  5181. DDPCAPS_8BIT,
  5182. ColorTable,
  5183. &pDevice->pDefaultPalette,
  5184. NULL);
  5185. DPF_UNMUTE();
  5186. }
  5187. }
  5188. if (pGblDriverData->hwCaps.dwDevCaps & D3DDEVCAPS_TEXTURESYSTEMMEMORY)
  5189. {
  5190. pDevice->bCanTextureSysmem = TRUE;
  5191. }
  5192. // Can this driver handle lightweight surfaces?
  5193. pDriverCaps->KnownDriverFlags = 0;
  5194. if (pDevice->DriverLevel < 7)
  5195. {
  5196. pDevice->bLightweight = FALSE;
  5197. }
  5198. else if (pDevice->DriverLevel == 7)
  5199. {
  5200. pDevice->bLightweight = CanKnownDriverDoThis(pDevice, KNOWN_LIGHTWEIGHT);
  5201. }
  5202. else
  5203. {
  5204. pDevice->bLightweight = TRUE;
  5205. }
  5206. // What about HW cursor support?
  5207. // The check below needs to know the hardware driver level so it cannot use
  5208. // pDevice->DriverLevel since it may be set due to ref.
  5209. if (SWCursorForced())
  5210. {
  5211. pDriverCaps->D3DCaps.CursorCaps = 0;
  5212. }
  5213. else if (((0 == pdrv->lpD3DExtendedCaps) ||
  5214. (0 == pDriverCaps->D3DCaps.MaxStreams)) &&
  5215. (NULL != pdrv->lpDDCBtmp->HALDDMiscellaneous2.GetDriverState))
  5216. {
  5217. // The hardware driver is DX7
  5218. if (CanKnownDriverDoThis(pDevice, KNOWN_HWCURSOR))
  5219. {
  5220. pDriverCaps->D3DCaps.CursorCaps = D3DCURSORCAPS_COLOR;
  5221. pDriverCaps->KnownDriverFlags |= KNOWN_HWCURSOR;
  5222. if (CanKnownDriverDoThis(pDevice, KNOWN_HWCURSORLOWRES))
  5223. {
  5224. pDriverCaps->D3DCaps.CursorCaps |= D3DCURSORCAPS_LOWRES;
  5225. pDriverCaps->KnownDriverFlags |= KNOWN_HWCURSORLOWRES;
  5226. }
  5227. }
  5228. }
  5229. // If it's a pre-dx8 driver and they support cubemaps, we need to
  5230. // specify whether they support mipped cubemaps or not.
  5231. if (pDevice->DriverLevel < 8)
  5232. {
  5233. if (CanKnownDriverDoThis(pDevice, KNOWN_MIPPEDCUBEMAPS))
  5234. {
  5235. pDriverCaps->KnownDriverFlags |= KNOWN_MIPPEDCUBEMAPS;
  5236. }
  5237. // Does this driver have a Z/Stencil depth restriction?
  5238. if (CanKnownDriverDoThis(pDevice, KNOWN_ZSTENCILDEPTH))
  5239. {
  5240. pDriverCaps->KnownDriverFlags |= KNOWN_ZSTENCILDEPTH;
  5241. }
  5242. // Does device have no driver known to over-queue windowed presentation blts?
  5243. if (CanKnownDriverDoThis(pDevice, KNOWN_NOTAWINDOWEDBLTQUEUER))
  5244. {
  5245. pDriverCaps->KnownDriverFlags |= KNOWN_NOTAWINDOWEDBLTQUEUER;
  5246. }
  5247. // Does device support D3DFMT_D16_LOCKABLE
  5248. if (CanKnownDriverDoThis(pDevice, KNOWN_D16_LOCKABLE))
  5249. {
  5250. pDriverCaps->KnownDriverFlags |= KNOWN_D16_LOCKABLE;
  5251. }
  5252. // Figure out what RT/Texture formats it supports
  5253. if (CanKnownDriverDoThis(pDevice, KNOWN_CANMISMATCHRT))
  5254. {
  5255. pDriverCaps->KnownDriverFlags |= KNOWN_CANMISMATCHRT;
  5256. }
  5257. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_X1R5G5B5))
  5258. {
  5259. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_X1R5G5B5;
  5260. }
  5261. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_R5G6B5))
  5262. {
  5263. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_R5G6B5;
  5264. }
  5265. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_X8R8G8B8))
  5266. {
  5267. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_X8R8G8B8;
  5268. }
  5269. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_A8R8G8B8))
  5270. {
  5271. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_A8R8G8B8;
  5272. }
  5273. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_A1R5G5B5))
  5274. {
  5275. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_A1R5G5B5;
  5276. }
  5277. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_A4R4G4B4))
  5278. {
  5279. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_A4R4G4B4;
  5280. }
  5281. }
  5282. // ATI drivers don't handle palettes correctly, so we will delete
  5283. // all palettized textures from their list.
  5284. if (pDevice->DriverLevel < 8)
  5285. {
  5286. if (((pDevice->PCIID >> 16) == 0x1002) &&
  5287. (pTextureFormats != NULL))
  5288. {
  5289. i = 0;
  5290. while (i < *pcTextureFormats)
  5291. {
  5292. if (pTextureFormats[i].ddpfPixelFormat.dwFlags &
  5293. (DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8))
  5294. {
  5295. UINT j;
  5296. (*pcTextureFormats)--;
  5297. for (j = i; j < *pcTextureFormats; j++)
  5298. {
  5299. pTextureFormats[j] = pTextureFormats[j+1];
  5300. }
  5301. }
  5302. else
  5303. {
  5304. i++;
  5305. }
  5306. }
  5307. }
  5308. }
  5309. // We assume that a software driver will always support at least DX7
  5310. if ((pDevice->DriverLevel < 7) &&
  5311. IS_SOFTWARE_DRIVER(pDevice))
  5312. {
  5313. LEAVE_DDRAW();
  5314. DPF_ERR("A Software rasterizer must contain at least DX7 driver level support");
  5315. return FALSE;
  5316. }
  5317. LEAVE_DDRAW();
  5318. return TRUE;
  5319. }
  5320. VOID CleanupDevice (PDDDEVICEHANDLE pDevice)
  5321. {
  5322. DWORD i;
  5323. DDSURFACE* pSurf;
  5324. DDSURFACE* pSurfTemp;
  5325. // Cleanup the palette allocations
  5326. if (pDevice->pDefaultPalette != NULL)
  5327. {
  5328. InternalPaletteRelease((LPDDRAWI_DDRAWPALETTE_INT)
  5329. pDevice->pDefaultPalette);
  5330. pDevice->pDefaultPalette = NULL;
  5331. }
  5332. if (pDevice->NumPaletteHandleEntries > 0)
  5333. {
  5334. for (i = 0; i < pDevice->NumPaletteHandleEntries; i++)
  5335. {
  5336. if (pDevice->pPaletteHandleTable[i] != NULL)
  5337. {
  5338. InternalPaletteRelease((LPDDRAWI_DDRAWPALETTE_INT)
  5339. pDevice->pPaletteHandleTable[i]->pDDPalette);
  5340. MemFree(pDevice->pPaletteHandleTable[i]);
  5341. pDevice->pPaletteHandleTable[i] = NULL;
  5342. }
  5343. }
  5344. MemFree(pDevice->pPaletteHandleTable);
  5345. pDevice->pPaletteHandleTable = NULL;
  5346. pDevice->NumPaletteHandleEntries = 0;
  5347. }
  5348. if (pDevice->pContext)
  5349. {
  5350. D3D8_CONTEXTDESTROYDATA data;
  5351. data.dwhContext = (ULONG_PTR) pDevice->pContext;
  5352. D3dContextDestroy(&data);
  5353. pDevice->pContext = NULL;
  5354. }
  5355. pSurf = pDevice->pSurfList;
  5356. while (pSurf != NULL)
  5357. {
  5358. if (!IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  5359. {
  5360. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  5361. {
  5362. LPDDRAWI_DDRAWSURFACE_INT pHeavy;
  5363. pHeavy = MapLightweightSurface(pSurf);
  5364. if (pHeavy != NULL)
  5365. {
  5366. pHeavy->dwIntRefCnt = 1;
  5367. pHeavy->lpLcl->dwLocalRefCnt = 1;
  5368. pHeavy->lpLcl->lpGbl->dwRefCnt = 1;
  5369. if (pSurf->dwFlags & DDSURFACE_ROOT)
  5370. {
  5371. pHeavy->lpLcl->lpSurfMore->pAddrefedThisOwner = (IUnknown*) pSurf->pDevice->pDD;
  5372. }
  5373. InternalSurfaceRelease(pHeavy, TRUE, TRUE);
  5374. pHeavy->dwReserved1 = (ULONG_PTR) NULL;
  5375. pHeavy->dwReserved2 = 0;
  5376. }
  5377. MemFree (pSurf->Surface.pLight);
  5378. pSurf->Surface.pLight = NULL;
  5379. }
  5380. else if (pSurf->dwFlags & DDSURFACE_HEAVYWEIGHT)
  5381. {
  5382. if ((pSurf->dwFlags & DDSURFACE_ROOT) &&
  5383. (pSurf->Surface.pHeavy != NULL))
  5384. {
  5385. InternalSurfaceRelease(pSurf->Surface.pHeavy, FALSE, TRUE);
  5386. }
  5387. }
  5388. }
  5389. else
  5390. {
  5391. MemFree(pSurf->Surface.pHeavy);
  5392. }
  5393. pSurfTemp = pSurf;
  5394. pSurf = pSurf->pNext;
  5395. MemFree(pSurfTemp);
  5396. }
  5397. if (pDevice->pSwDD)
  5398. {
  5399. if (pDevice->pSwDD->lpLcl->lpGbl->lpDDCBtmp)
  5400. {
  5401. MemFree(pDevice->pSwDD->lpLcl->lpGbl->lpDDCBtmp);
  5402. }
  5403. MemFree(pDevice->pSwDD);
  5404. }
  5405. if (pDevice->NumCachedSurfaces > 0)
  5406. {
  5407. for (i = 0; i < (DWORD) pDevice->NumCachedSurfaces; i++)
  5408. {
  5409. MemFree(pDevice->pCachedSurfaceTable[i].pSurface);
  5410. }
  5411. MemFree(pDevice->pCachedSurfaceTable);
  5412. pDevice->pCachedSurfaceTable = NULL;
  5413. pDevice->NumCachedSurfaces = 0;
  5414. }
  5415. if (pDevice->SurfaceHandleList.dwList != NULL)
  5416. {
  5417. MemFree(pDevice->SurfaceHandleList.dwList);
  5418. }
  5419. }
  5420. VOID APIENTRY D3D8DeleteDirectDrawObject( HANDLE hDD )
  5421. {
  5422. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
  5423. LPDIRECTDRAW lpDD;
  5424. // hDD can be NULL in some error paths
  5425. if (pDevice == NULL)
  5426. return;
  5427. ENTER_DDRAW();
  5428. CleanupDevice(pDevice);
  5429. lpDD = (LPDIRECTDRAW) pDevice->pDD;
  5430. if (lpDD != NULL)
  5431. {
  5432. lpDD->lpVtbl->Release(lpDD);
  5433. }
  5434. if (pDeviceList == pDevice)
  5435. {
  5436. // If we're first, then update global list
  5437. // pointer
  5438. pDeviceList = pDevice->pLink;
  5439. }
  5440. else
  5441. {
  5442. // Find ourselves in the list
  5443. PDDDEVICEHANDLE pDevicePrev = pDeviceList;
  5444. while (pDevicePrev->pLink != pDevice)
  5445. {
  5446. pDevicePrev = pDevicePrev->pLink;
  5447. }
  5448. // Skip past our current node
  5449. pDevicePrev->pLink = pDevice->pLink;
  5450. }
  5451. MemFree(pDevice);
  5452. LEAVE_DDRAW();
  5453. }
  5454. HDC APIENTRY D3D8GetDC( HANDLE hSurface, LPPALETTEENTRY pPalette )
  5455. {
  5456. HDC hdc = NULL;
  5457. PDDSURFACE pSurf = (PDDSURFACE) hSurface;
  5458. LPDDRAWI_DDRAWSURFACE_INT pHeavy;
  5459. if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  5460. {
  5461. DDSURFACEDESC ddsd;
  5462. ddsd.dwSize = sizeof(ddsd);
  5463. pHeavy = GetHeavyweightSurf(pSurf);
  5464. if (pHeavy == NULL)
  5465. {
  5466. hdc = NULL;
  5467. DPF_ERR("Out of memory error mapping lightweight surface");
  5468. }
  5469. else
  5470. {
  5471. FillDDSurfaceDesc(pHeavy->lpLcl, &ddsd);
  5472. ddsd.lpSurface = (void*)pHeavy->lpLcl->lpGbl->fpVidMem;
  5473. hdc = DD16_GetDC((HDC)(pSurf->pDevice->pDD->lpLcl->hDC),
  5474. &ddsd,
  5475. NULL);
  5476. if (hdc == NULL)
  5477. {
  5478. DPF_ERR("Failure to GetDC for non-heavyweight surface?");
  5479. }
  5480. DONE_HEAVYWEIGHT_SURF (pSurf);
  5481. }
  5482. }
  5483. else
  5484. {
  5485. pHeavy = GetHeavyweightSurf(pSurf);
  5486. if (pHeavy == NULL)
  5487. {
  5488. DPF_ERR("Unable to map lightweight surface - out of memory");
  5489. hdc = NULL;
  5490. }
  5491. else
  5492. {
  5493. HRESULT hr = InternalGetDC(pHeavy, &hdc, FALSE);
  5494. if (FAILED(hr))
  5495. {
  5496. DPF_ERR("Could not get DC for surface");
  5497. hdc = NULL;
  5498. }
  5499. }
  5500. }
  5501. return hdc;
  5502. }
  5503. BOOL APIENTRY D3D8ReleaseDC(HANDLE hSurface, HDC hdc)
  5504. {
  5505. PDDSURFACE pSurf = (PDDSURFACE) hSurface;
  5506. DDASSERT(hdc != NULL);
  5507. if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  5508. {
  5509. DD16_ReleaseDC(hdc);
  5510. }
  5511. else
  5512. {
  5513. HRESULT hr;
  5514. LPDDRAWI_DDRAWSURFACE_INT pHeavy;
  5515. if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
  5516. {
  5517. pHeavy = GET_CACHED_LIGHTWEIGHT_INT(pSurf);
  5518. DDASSERT(pHeavy != NULL);
  5519. }
  5520. else
  5521. {
  5522. pHeavy = pSurf->Surface.pHeavy;
  5523. }
  5524. hr = InternalReleaseDC(pHeavy->lpLcl, hdc, FALSE);
  5525. if (FAILED(hr))
  5526. {
  5527. DPF_ERR("Could not release DC?");
  5528. }
  5529. DONE_HEAVYWEIGHT_SURF(pSurf);
  5530. }
  5531. return TRUE;
  5532. }
  5533. BOOL APIENTRY D3D8SetGammaRamp( HANDLE hDD, HDC hdc, LPVOID lpGammaRamp )
  5534. {
  5535. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
  5536. HRESULT hr = E_FAIL;
  5537. ENTER_BOTH();
  5538. if (CheckForDeviceLost(hDD))
  5539. {
  5540. LEAVE_BOTH();
  5541. return TRUE;
  5542. }
  5543. if (pDevice->pDD->lpLcl->lpPrimary != NULL)
  5544. {
  5545. hr = DD_Gamma_SetGammaRamp((LPDIRECTDRAWGAMMACONTROL) pDevice->pDD->lpLcl->lpPrimary,
  5546. 0, lpGammaRamp);
  5547. }
  5548. LEAVE_BOTH();
  5549. if (SUCCEEDED(hr))
  5550. {
  5551. return TRUE;
  5552. }
  5553. return FALSE;
  5554. }
  5555. // D3D8BuildModeTable
  5556. //
  5557. VOID APIENTRY D3D8BuildModeTable( char* pDeviceName,
  5558. D3DDISPLAYMODE* pTable,
  5559. DWORD* pNumEntries,
  5560. D3DFORMAT Unknown16,
  5561. HANDLE hProfile,
  5562. BOOL b16bppSupported,
  5563. BOOL b32bppSupported
  5564. )
  5565. {
  5566. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hProfile;
  5567. LPDDRAWI_DIRECTDRAW_GBL pdrv;
  5568. DWORD NumModes = 0;
  5569. DWORD i;
  5570. DWORD j;
  5571. D3DFORMAT format;
  5572. if ((pDeviceHandle == NULL) ||
  5573. (pDeviceHandle->pDD == NULL))
  5574. {
  5575. *pNumEntries = NumModes;
  5576. return;
  5577. }
  5578. ENTER_DDRAW();
  5579. pdrv = pDeviceHandle->pDD->lpLcl->lpGbl;
  5580. NumModes = 0;
  5581. for (i = 0; i < pdrv->dwNumModes; i++)
  5582. {
  5583. // Filter out all modes other than 15, 16 and 32bpp
  5584. if ((pdrv->lpModeInfo[i].dwBPP != 15) &&
  5585. (pdrv->lpModeInfo[i].dwBPP != 16) &&
  5586. (pdrv->lpModeInfo[i].dwBPP != 32))
  5587. {
  5588. continue;
  5589. }
  5590. if (((pdrv->lpModeInfo[i].dwBPP == 15) ||
  5591. (pdrv->lpModeInfo[i].dwBPP == 16)) &&
  5592. !b16bppSupported)
  5593. {
  5594. continue;
  5595. }
  5596. else if ((pdrv->lpModeInfo[i].dwBPP == 32) &&
  5597. !b32bppSupported)
  5598. {
  5599. continue;
  5600. }
  5601. // Can GDI and the monitor handle this mode/refresh rate?
  5602. if(pdrv->dwFlags & DDRAWI_DISPLAYDRV)
  5603. {
  5604. DWORD cds_flags;
  5605. DEVMODE dm;
  5606. int cds_rc;
  5607. BOOL bUseRefresh;
  5608. bUseRefresh = (pdrv->lpModeInfo[i].wRefreshRate > 0);
  5609. makeDEVMODE( pdrv, &pdrv->lpModeInfo[i], FALSE, bUseRefresh, &cds_flags, &dm );
  5610. cds_flags |= CDS_TEST;
  5611. cds_rc = xxxChangeDisplaySettingsExA(pdrv->cDriverName, &dm, NULL, cds_flags, 0);
  5612. if( cds_rc != 0 )
  5613. {
  5614. continue;
  5615. }
  5616. if (!MonitorCanHandleMode (pdrv,
  5617. pdrv->lpModeInfo[i].dwWidth,
  5618. pdrv->lpModeInfo[i].dwHeight,
  5619. pdrv->lpModeInfo[i].wRefreshRate))
  5620. {
  5621. continue;
  5622. }
  5623. }
  5624. // Make sure that we understand the format.
  5625. if ((pdrv->lpModeInfo[i].dwBPP == 16) ||
  5626. (pdrv->lpModeInfo[i].dwBPP == 15))
  5627. {
  5628. format = Unknown16;
  5629. }
  5630. else
  5631. {
  5632. DDASSERT(pdrv->lpModeInfo[i].dwBPP == 32);
  5633. format = D3DFMT_X8R8G8B8;
  5634. }
  5635. // Add the new mode.
  5636. if (pTable != NULL)
  5637. {
  5638. ///The caller must pass us a number
  5639. DDASSERT( (*pNumEntries) );
  5640. if ( NumModes >= *pNumEntries )
  5641. {
  5642. //we exceeded the number of entries allocated for us.
  5643. //tell the caller to re-query and try again.
  5644. NumModes = 0;
  5645. break;
  5646. }
  5647. pTable[NumModes].Width = pdrv->lpModeInfo[i].dwWidth;
  5648. pTable[NumModes].Height = pdrv->lpModeInfo[i].dwHeight;
  5649. pTable[NumModes].RefreshRate = pdrv->lpModeInfo[i].wRefreshRate;
  5650. pTable[NumModes].Format = format;
  5651. }
  5652. NumModes++;
  5653. }
  5654. LEAVE_DDRAW();
  5655. *pNumEntries = NumModes;
  5656. }
  5657. BOOL APIENTRY D3D8IsDeviceLost( HANDLE hDD)
  5658. {
  5659. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
  5660. return pDevice->bDeviceLost;
  5661. }
  5662. BOOL APIENTRY D3D8CanRestoreNow( HANDLE hDD)
  5663. {
  5664. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
  5665. LPDDRAWI_DIRECTDRAW_GBL pGbl;
  5666. BOOL bSupported = FALSE;
  5667. HRESULT hr;
  5668. // If we aren't lost, then it's an easy call
  5669. ENTER_DDRAW();
  5670. if (!(pDevice->bDeviceLost))
  5671. {
  5672. LEAVE_DDRAW();
  5673. return TRUE;
  5674. }
  5675. hr = DD_TestCooperativeLevel((LPDIRECTDRAW)pDevice->pDD);
  5676. if ( DD_OK == hr || DDERR_WRONGMODE == hr)
  5677. {
  5678. // Are we in a mode in which D3D is supported?
  5679. pGbl = pDevice->pDD->lpLcl->lpGbl;
  5680. if (IS_SOFTWARE_DRIVER(hDD))
  5681. {
  5682. // Assume that any software driver can render in modes > 8bpp
  5683. if (pGbl->vmiData.ddpfDisplay.dwRGBBitCount > 8)
  5684. {
  5685. bSupported = TRUE;
  5686. }
  5687. }
  5688. if (pGbl->lpD3DGlobalDriverData != NULL)
  5689. {
  5690. switch (pGbl->vmiData.ddpfDisplay.dwRGBBitCount)
  5691. {
  5692. case 15:
  5693. case 16:
  5694. if (pGbl->lpD3DGlobalDriverData->hwCaps.dwDeviceRenderBitDepth & DDBD_16)
  5695. {
  5696. bSupported = TRUE;
  5697. }
  5698. break;
  5699. case 24:
  5700. if (pGbl->lpD3DGlobalDriverData->hwCaps.dwDeviceRenderBitDepth & DDBD_24)
  5701. {
  5702. bSupported = TRUE;
  5703. }
  5704. break;
  5705. case 32:
  5706. if (pGbl->lpD3DGlobalDriverData->hwCaps.dwDeviceRenderBitDepth & DDBD_32)
  5707. {
  5708. bSupported = TRUE;
  5709. }
  5710. break;
  5711. }
  5712. }
  5713. }
  5714. LEAVE_DDRAW();
  5715. return bSupported;
  5716. }
  5717. VOID APIENTRY D3D8RestoreDevice( HANDLE hDD)
  5718. {
  5719. HRESULT hr;
  5720. DWORD i, j, k;
  5721. DWORD Width, Height, Depth;
  5722. BYTE *SliceSrc, *SliceDst, *RowSrc, *RowDst;
  5723. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
  5724. PDDSURFACE pSurf;
  5725. LPDDRAWI_DDRAWSURFACE_INT pHeavy;
  5726. PDEFERREDCREATE pDefCreate = pDevice->pDeferList;
  5727. PDEFERREDCREATE *ppNext = &pDevice->pDeferList;
  5728. PDEFERREDCREATE pTemp;
  5729. D3D8_LOCKDATA LockData;
  5730. D3D8_UNLOCKDATA UnlockData;
  5731. ENTER_BOTH();
  5732. if (!D3D8CanRestoreNow(hDD))
  5733. {
  5734. LEAVE_BOTH();
  5735. return;
  5736. }
  5737. pDevice->bDeviceLost = FALSE;
  5738. pDevice->bDP2Error = FALSE;
  5739. // If a context was created while lost, we will not re-create it now since
  5740. // we don't have a render target or Z Buffer (the vidmem surfaces would have
  5741. // already been destroyed. Therefore, we won't attempt to create the context
  5742. // until they create the new surfaces and call SetRenderTarget. We also
  5743. // won't try to create any defered texture handles at this time since we may
  5744. // not have a valid context. We will also do that in the SetRenderTarget call.
  5745. // Walk the list of surfaces and create any SurfaceEx surfaces that we may
  5746. // have pending.
  5747. pSurf = pDevice->pSurfList;
  5748. while (pSurf != NULL)
  5749. {
  5750. if ((pSurf->dwFlags & DDSURFACE_DEFERCREATEEX) &&
  5751. !(pSurf->dwFlags & DDSURFACE_DUMMY))
  5752. {
  5753. pHeavy = GetHeavyweightSurf(pSurf);
  5754. if (pHeavy != NULL)
  5755. {
  5756. createsurfaceEx(pHeavy->lpLcl);
  5757. DONE_HEAVYWEIGHT_SURF(pSurf);
  5758. }
  5759. pSurf->dwFlags &= ~DDSURFACE_DEFERCREATEEX;
  5760. }
  5761. pSurf = pSurf->pNext;
  5762. }
  5763. // Finally resurrect our deferred driver managed surfaces (Gulp!)
  5764. while (pDefCreate != NULL)
  5765. {
  5766. // First check if the deferred surface exists at all. The problem
  5767. // is that DdDestroySurface could have been called. We could have
  5768. // removed the surface from the deferred list in DdDestroySurface
  5769. // but since DdDestroySurface is called piecemeal, it gets
  5770. // very annoying. The removal is best done here.
  5771. // ASSUMPTION: if pSList[0].hKernelHandle is NULL then
  5772. // pSList[1,2,etc].hKernelHandle are also NULL. There is no
  5773. // reason for this to be not the case as of 3/2001.
  5774. if (pDefCreate->CreateData.pSList[0].hKernelHandle == NULL)
  5775. {
  5776. pTemp = pDefCreate->pNext;
  5777. *ppNext = pTemp;
  5778. MemFree(pDefCreate->CreateData.pSList);
  5779. MemFree(pDefCreate);
  5780. pDefCreate = pTemp;
  5781. continue;
  5782. }
  5783. // Attempt to resurrect
  5784. pDefCreate->CreateData.bReUse = TRUE;
  5785. hr = DdCreateSurface(&pDefCreate->CreateData);
  5786. if (SUCCEEDED(hr))
  5787. {
  5788. for (i = 0; i < pDefCreate->CreateData.dwSCnt; i++)
  5789. {
  5790. pSurf = (PDDSURFACE) pDefCreate->CreateData.pSList[i].hKernelHandle;
  5791. // Reset DDSURF_SYSMEMALLOCATED to keep DdLock below happy
  5792. pSurf->dwFlags &= ~DDSURFACE_SYSMEMALLOCATED;
  5793. // Lock and copy
  5794. ZeroMemory(&LockData, sizeof(LockData));
  5795. LockData.hDD = hDD;
  5796. LockData.hSurface = pSurf;
  5797. hr = DdLock(&LockData);
  5798. if (SUCCEEDED(hr))
  5799. {
  5800. SliceSrc = (BYTE*)pSurf->fpVidMem;
  5801. SliceDst = (BYTE*)LockData.lpSurfData;
  5802. Width = pDefCreate->CreateData.pSList[i].cpWidth;
  5803. Height = pDefCreate->CreateData.pSList[i].cpHeight;
  5804. Depth = pDefCreate->CreateData.pSList[i].cpDepth;
  5805. if (!(pDefCreate->CreateData.Type == D3DRTYPE_VOLUME ||
  5806. pDefCreate->CreateData.Type == D3DRTYPE_VOLUMETEXTURE))
  5807. {
  5808. Depth = 1;
  5809. }
  5810. for (j = 0; j < Depth; ++j)
  5811. {
  5812. RowSrc = SliceSrc;
  5813. RowDst = SliceDst;
  5814. for (k = 0; k < Height; ++k)
  5815. {
  5816. CopyMemory(RowDst, RowSrc, min(LockData.lPitch, (LONG)Width * 8));
  5817. RowSrc += Width * 8;
  5818. RowDst += LockData.lPitch;
  5819. }
  5820. SliceSrc += Width * Height * 8;
  5821. SliceDst += LockData.lSlicePitch;
  5822. }
  5823. ZeroMemory(&UnlockData, sizeof(UnlockData));
  5824. UnlockData.hDD = hDD;
  5825. UnlockData.hSurface = pSurf;
  5826. hr = DdUnlock(&UnlockData);
  5827. if (FAILED(hr))
  5828. {
  5829. // TODO: Handle/(ignore?) failure
  5830. DPF(0,"Unlock failed when resurrecting driver managed surface.");
  5831. }
  5832. }
  5833. else
  5834. {
  5835. // TODO: Handle/(ignore?) failure
  5836. DPF(0,"Lock failed when resurrecting driver managed surface. Texture may go missing.");
  5837. }
  5838. // Free the temporary fpVidmem that we allocated in CreateVidmemSurface
  5839. MemFree(pSurf->fpVidMem);
  5840. pSurf->fpVidMem = 0;
  5841. }
  5842. // Remove from list and freeup all memory
  5843. pTemp = pDefCreate->pNext;
  5844. *ppNext = pTemp;
  5845. MemFree(pDefCreate->CreateData.pSList);
  5846. MemFree(pDefCreate);
  5847. pDefCreate = pTemp;
  5848. }
  5849. else
  5850. {
  5851. // We set ReUse to FALSE to indicate that we were not able to resurrect
  5852. pDefCreate->CreateData.bReUse = FALSE;
  5853. ppNext = &(pDefCreate->pNext);
  5854. pDefCreate = pDefCreate->pNext;
  5855. }
  5856. }
  5857. if (pDevice->pDeferList != NULL)
  5858. {
  5859. // TODO:
  5860. // Ummm, we were not able to resurrect. This may be due to out of memory
  5861. // which probably needs to be reported to the app.
  5862. DPF(0,"Unable to resurrect all driver managed surfaces.");
  5863. }
  5864. LEAVE_BOTH();
  5865. }
  5866. BOOL APIENTRY D3D8DoVidmemSurfacesExist( HANDLE hDD)
  5867. {
  5868. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  5869. PDDSURFACE pSurf;
  5870. // Walk the list and return TRUE is we find any surfaces that are either
  5871. // local or nonlocal vidmem.
  5872. ENTER_DDRAW();
  5873. pSurf = pDeviceHandle->pSurfList;
  5874. while (pSurf != NULL)
  5875. {
  5876. if ((pSurf->Pool == D3DPOOL_LOCALVIDMEM) ||
  5877. (pSurf->Pool == D3DPOOL_NONLOCALVIDMEM) ||
  5878. (pSurf->dwFlags & DDSURFACE_TREATASVIDMEM))
  5879. {
  5880. #if DBG
  5881. DPF(0,"The following D3DPOOL_DEFAULT surfaces/buffers/textures still exist");
  5882. pSurf = pDeviceHandle->pSurfList;
  5883. while (pSurf != NULL)
  5884. {
  5885. if ((pSurf->Pool == D3DPOOL_LOCALVIDMEM) ||
  5886. (pSurf->Pool == D3DPOOL_NONLOCALVIDMEM) ||
  5887. (pSurf->dwFlags & DDSURFACE_TREATASVIDMEM))
  5888. {
  5889. switch (pSurf->Type)
  5890. {
  5891. case D3DRTYPE_SURFACE:
  5892. DPF(0," D3DRTYPE_SURFACE");
  5893. break;
  5894. case D3DRTYPE_VOLUME:
  5895. DPF(0," D3DRTYPE_VOLUME");
  5896. break;
  5897. case D3DRTYPE_TEXTURE:
  5898. DPF(0," D3DRTYPE_TEXTURE");
  5899. break;
  5900. case D3DRTYPE_VOLUMETEXTURE:
  5901. DPF(0," D3DRTYPE_VOLUMETEXTURE");
  5902. break;
  5903. case D3DRTYPE_CUBETEXTURE:
  5904. DPF(0," D3DRTYPE_CUBETEXTURE");
  5905. break;
  5906. case D3DRTYPE_VERTEXBUFFER:
  5907. DPF(0," D3DRTYPE_VERTEXBUFFER");
  5908. break;
  5909. case D3DRTYPE_INDEXBUFFER:
  5910. DPF(0," D3DRTYPE_INDEXBUFFER");
  5911. break;
  5912. case D3DRTYPE_COMMANDBUFFER:
  5913. DPF(0," D3DRTYPE_COMMANDBUFFER");
  5914. break;
  5915. default:
  5916. DPF(0," UNKNOWN SURFACE TYPE");
  5917. break;
  5918. }
  5919. }
  5920. pSurf = pSurf->pNext;
  5921. }
  5922. #endif
  5923. LEAVE_DDRAW();
  5924. return TRUE;
  5925. }
  5926. pSurf = pSurf->pNext;
  5927. }
  5928. LEAVE_DDRAW();
  5929. return FALSE;
  5930. }
  5931. DWORD APIENTRY D3D8GetMode( HANDLE Handle,
  5932. char* pDeviceName,
  5933. D3DDISPLAYMODE* pMode,
  5934. D3DFORMAT Unknown16)
  5935. {
  5936. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) Handle;
  5937. LPDDRAWI_DIRECTDRAW_GBL pdrv;
  5938. ENTER_DDRAW();
  5939. memset(pMode, 0, sizeof(D3DDISPLAYMODE));
  5940. if (pDeviceHandle != NULL)
  5941. {
  5942. pdrv = pDeviceHandle->pDD->lpLcl->lpGbl;
  5943. pMode->Width = pdrv->vmiData.dwDisplayWidth;
  5944. pMode->Height = pdrv->vmiData.dwDisplayHeight;
  5945. pMode->RefreshRate = pdrv->dwMonitorFrequency;
  5946. switch (pdrv->vmiData.ddpfDisplay.dwRGBBitCount)
  5947. {
  5948. case 8:
  5949. pMode->Format = D3DFMT_P8;
  5950. break;
  5951. case 15:
  5952. case 16:
  5953. if (pdrv->vmiData.ddpfDisplay.dwGBitMask == 0x7e0)
  5954. {
  5955. pMode->Format = D3DFMT_R5G6B5;
  5956. }
  5957. else
  5958. {
  5959. pMode->Format = D3DFMT_X1R5G5B5;
  5960. }
  5961. break;
  5962. case 24:
  5963. pMode->Format = D3DFMT_R8G8B8;
  5964. break;
  5965. case 32:
  5966. pMode->Format = D3DFMT_X8R8G8B8;
  5967. break;
  5968. default:
  5969. pMode->Format = D3DFMT_UNKNOWN;
  5970. break;
  5971. }
  5972. LEAVE_DDRAW();
  5973. return DD_OK;
  5974. }
  5975. else
  5976. {
  5977. DEVMODE dm;
  5978. HDC hdc;
  5979. memset (&dm, 0, sizeof(dm));
  5980. dm.dmSize = sizeof(dm);
  5981. // For pre-Win98 systems, we use GetDeviceCaps
  5982. // because ENUM_CURRENT_SETTINGS is not
  5983. // supported on these legacy systems.
  5984. if (!IsWindows98())
  5985. {
  5986. DWORD bpp;
  5987. hdc = GetDC(NULL);
  5988. pMode->Width = GetDeviceCaps(hdc, HORZRES);
  5989. pMode->Height = GetDeviceCaps(hdc, VERTRES);
  5990. pMode->RefreshRate = 0;
  5991. bpp = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
  5992. ReleaseDC(NULL, hdc);
  5993. switch (bpp)
  5994. {
  5995. case 8:
  5996. pMode->Format = D3DFMT_P8;
  5997. break;
  5998. case 24:
  5999. pMode->Format = D3DFMT_R8G8B8;
  6000. break;
  6001. case 32:
  6002. pMode->Format = D3DFMT_X8R8G8B8;
  6003. break;
  6004. case 15:
  6005. case 16:
  6006. pMode->Format = Unknown16;
  6007. break;
  6008. default:
  6009. DPF(0, "Unknown desktop format");
  6010. pMode->Format = D3DFMT_UNKNOWN;
  6011. break;
  6012. }
  6013. }
  6014. else if (EnumDisplaySettings(pDeviceName, ENUM_CURRENT_SETTINGS, &dm))
  6015. {
  6016. pMode->Width = dm.dmPelsWidth;
  6017. pMode->Height = dm.dmPelsHeight;
  6018. pMode->RefreshRate = dm.dmDisplayFrequency;
  6019. switch (dm.dmBitsPerPel)
  6020. {
  6021. case 8:
  6022. pMode->Format = D3DFMT_P8;
  6023. break;
  6024. case 24:
  6025. pMode->Format = D3DFMT_R8G8B8;
  6026. break;
  6027. case 32:
  6028. pMode->Format = D3DFMT_X8R8G8B8;
  6029. break;
  6030. case 15:
  6031. case 16:
  6032. pMode->Format = Unknown16;
  6033. break;
  6034. default:
  6035. pMode->Format = D3DFMT_UNKNOWN;
  6036. break;
  6037. }
  6038. }
  6039. else
  6040. {
  6041. LEAVE_DDRAW();
  6042. DPF_ERR("EnumDisplaySettings failed?");
  6043. DPF(0, "display is %s", pDeviceName);
  6044. return D3DERR_DRIVERINTERNALERROR;
  6045. }
  6046. LEAVE_DDRAW();
  6047. return DD_OK;
  6048. }
  6049. LEAVE_DDRAW();
  6050. return D3DERR_DRIVERINTERNALERROR;
  6051. }
  6052. DWORD APIENTRY D3D8SetMode( HANDLE Handle,
  6053. char* pDeviceName,
  6054. UINT Width,
  6055. UINT Height,
  6056. UINT BPP,
  6057. UINT RefreshRate,
  6058. BOOL bRestore)
  6059. {
  6060. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) Handle;
  6061. LPDDRAWI_DIRECTDRAW_GBL pdrv;
  6062. HRESULT hr = DDERR_GENERIC;
  6063. DWORD i;
  6064. ENTER_DDRAW();
  6065. if ((pDeviceHandle != NULL) &&
  6066. (pDeviceHandle->pDD != NULL))
  6067. {
  6068. // We will call DDraw to do the mode change because it is able to
  6069. // cleanup the mode change when the app exits and because we don't
  6070. // want to treat external mode changes and DDraw mode changes the
  6071. // same way.
  6072. pdrv = pDeviceHandle->pDD->lpLcl->lpGbl;
  6073. for (i = 0; i < pdrv->dwNumModes; i++)
  6074. {
  6075. if ((pdrv->lpModeInfo[i].dwWidth == Width) &&
  6076. (pdrv->lpModeInfo[i].dwHeight == Height) &&
  6077. (pdrv->lpModeInfo[i].dwBPP == BPP))
  6078. {
  6079. if ((RefreshRate == 0) ||
  6080. (RefreshRate == pdrv->lpModeInfo[i].wRefreshRate))
  6081. {
  6082. break;
  6083. }
  6084. }
  6085. }
  6086. if (i < pdrv->dwNumModes)
  6087. {
  6088. BOOL bExists;
  6089. BOOL bOwn;
  6090. LPDDRAWI_DIRECTDRAW_LCL lcl = pDeviceHandle->pDD->lpLcl;
  6091. // When profiling, we will be doing mode changes w/o holding
  6092. // exlusive mode, but we need ddraw to think that we have it in
  6093. // order to change bit depth.
  6094. CheckExclusiveMode(lcl, &bExists, &bOwn, FALSE, NULL, FALSE);
  6095. if (!bOwn)
  6096. {
  6097. if (bExists)
  6098. {
  6099. LEAVE_DDRAW();
  6100. return D3DERR_DRIVERINTERNALERROR;
  6101. }
  6102. lcl->lpGbl->lpExclusiveOwner = lcl;
  6103. }
  6104. if (bRestore)
  6105. {
  6106. hr = MapLegacyResult(RestoreDisplayMode (lcl, TRUE));
  6107. }
  6108. else
  6109. {
  6110. hr = MapLegacyResult(SetDisplayMode (lcl,
  6111. i,
  6112. TRUE,
  6113. RefreshRate != 0));
  6114. }
  6115. if (!bOwn)
  6116. {
  6117. // This check shouldn't be needed, but it's safe since just
  6118. // about anything can happen during a mode change.
  6119. if (lcl->lpGbl->lpExclusiveOwner == lcl)
  6120. {
  6121. lcl->lpGbl->lpExclusiveOwner = NULL;
  6122. }
  6123. }
  6124. }
  6125. }
  6126. LEAVE_DDRAW();
  6127. return hr;
  6128. }
  6129. DWORD APIENTRY D3D8SetCooperativeLevel(
  6130. HANDLE hDD,
  6131. HWND hWnd,
  6132. DWORD dwFlags )
  6133. {
  6134. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
  6135. LPDDRAWI_DIRECTDRAW_INT pdrv_int = pDevice->pDD;
  6136. return MapLegacyResult(DD_SetCooperativeLevel((LPDIRECTDRAW)pdrv_int, hWnd, dwFlags|DDSCL_DX8APP));
  6137. }
  6138. BOOL APIENTRY D3D8IsDummySurface(
  6139. HANDLE hSurface )
  6140. {
  6141. PDDSURFACE pSurf = (PDDSURFACE) hSurface;
  6142. return ((pSurf->dwFlags & DDSURFACE_DUMMY) != 0);
  6143. }
  6144. void CleanupD3D8( LPDDRAWI_DIRECTDRAW_GBL pdrv,
  6145. BOOL bDestroyAll,
  6146. DWORD PID)
  6147. {
  6148. DDDEVICEHANDLE* pDevice;
  6149. DDDEVICEHANDLE* pTemp;
  6150. ENTER_DDRAW();
  6151. pDevice = pDeviceList;
  6152. if (bDestroyAll)
  6153. {
  6154. // The process has died, so clean everything up. We don't need to call
  6155. // the software driver for anything since it's already unloaded.
  6156. while (pDevice != NULL)
  6157. {
  6158. if (pDevice->PID == PID)
  6159. {
  6160. CleanupDevice(pDevice);
  6161. // Remove this device from the list
  6162. if (pDeviceList == pDevice)
  6163. {
  6164. pDeviceList = pDevice->pLink;
  6165. }
  6166. else
  6167. {
  6168. pTemp = pDeviceList;
  6169. while (pTemp->pLink != pDevice)
  6170. {
  6171. pTemp = pTemp->pLink;
  6172. }
  6173. pTemp->pLink = pDevice->pLink;
  6174. }
  6175. // Now free the device
  6176. pTemp = pDevice;
  6177. pDevice = pDevice->pLink;
  6178. MemFree(pTemp);
  6179. }
  6180. else
  6181. {
  6182. pDevice = pDevice->pLink;
  6183. }
  6184. }
  6185. }
  6186. else
  6187. {
  6188. // The device is getting lost, so we will mark it as lost and free up
  6189. // any resources that will get lost.
  6190. while (pDevice != NULL)
  6191. {
  6192. if (pDevice->pDD->lpLcl->lpGbl == pdrv)
  6193. {
  6194. LoseDevice (pDevice);
  6195. }
  6196. pDevice = pDevice->pLink;
  6197. }
  6198. }
  6199. LEAVE_DDRAW();
  6200. }
  6201. VOID APIENTRY D3D8LoseDevice(
  6202. HANDLE hDD )
  6203. {
  6204. ENTER_DDRAW();
  6205. LoseDevice (hDD);
  6206. LEAVE_DDRAW();
  6207. }
  6208. VOID APIENTRY D3D8GetHALName(
  6209. char* pDisplayName,
  6210. char* pHALName)
  6211. {
  6212. LPDDRAWI_DIRECTDRAW_INT lpDD_int = NULL;
  6213. ENTER_DDRAW();
  6214. InternalDirectDrawCreate( NULL,
  6215. (LPDIRECTDRAW*) &lpDD_int,
  6216. NULL,
  6217. DDRAWILCL_DIRECTDRAW7 | DDRAWILCL_DIRECTDRAW8,
  6218. pDisplayName);
  6219. if (lpDD_int != NULL)
  6220. {
  6221. lstrcpy(pHALName, lpDD_int->lpLcl->lpGbl->dd32BitDriverData.szName);
  6222. DD_Release((LPDIRECTDRAW)lpDD_int);
  6223. }
  6224. LEAVE_DDRAW();
  6225. }