Source code of Windows XP (NT5)
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.

6135 lines
238 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: ddraw.c
  3. *
  4. * Client side stubs for the private DirectDraw system APIs.
  5. *
  6. * Created: 3-Dec-1995
  7. * Author: J. Andrew Goossen [andrewgo]
  8. *
  9. * Copyright (c) 1995-1999 Microsoft Corporation
  10. \**************************************************************************/
  11. #define _D3DTYPES_H_
  12. #define _D3DCAPS_H_
  13. #include "ddrawpr.h"
  14. //#include "ddrawgdi.h"
  15. #include <ddrawint.h>
  16. #include <d3dnthal.h>
  17. #include <winddi.h>
  18. #include <osthunk.h>
  19. #include "ddithunk.h"
  20. #include <d3d8sddi.h>
  21. #include <assert.h>
  22. #define _FACD3D 0x876
  23. #define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code )
  24. #define D3DERR_DEVICELOST MAKE_D3DHRESULT(2152)
  25. #define D3DERR_DRIVERINTERNALERROR MAKE_D3DHRESULT(2087)
  26. #define D3DERR_NOTAVAILABLE MAKE_D3DHRESULT(2154)
  27. #define D3DERR_OUTOFVIDEOMEMORY MAKE_D3DHRESULT(380)
  28. #define D3DERR_DEFERRED_DP2ERROR MAKE_D3DHRESULT(2158)
  29. typedef struct _KNOWNENTRY
  30. {
  31. DWORD PCIID;
  32. DWORD VersionMajor; // 0 means all versions
  33. DWORD VersionMinor; // 0 means all versions
  34. DWORD Flags;
  35. } KNOWNENTRY;
  36. // The buffer used by GetDriverInfo2 is constrained to the maximum size
  37. // specified below by restrictions in the Win2K kernel. It is vital that
  38. // all data passed to the driver and received from the driver via
  39. // GetDriverInfo2 fit within a buffer of this number of DWORDS.
  40. // This size has to be less than 1K to let the kernel do its own buffer
  41. // overwrite testing.
  42. #define MAX_GDI2_BUFFER_DWORD_SIZE (249)
  43. // Bogus value used to initialize write only fields when communicating
  44. // with the driver in debug builds
  45. #define BOGUS_FIELD_VALUE 0xBAADCAFEul
  46. // Some global variables used to track when surfaces are free for all devices
  47. // in the process. This is tricky since we don't keep a device list.
  48. DWORD GlobalUniqueness = 0;
  49. DWORD NumDevices = 0;
  50. DWORD NumReadyDevices = 0;
  51. //todo d16 for rage 128 series... need date/time
  52. //todo :G200, G400 new RT+Tex formats... need date/time
  53. //todo: Need driver date/time for Kyro: |KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8
  54. //todo: Trident 8420, 9910: need date/time for D16
  55. //todo: dates for SiS parts D16
  56. const KNOWNENTRY gKnownDeviceList[] =
  57. {
  58. // NVidia
  59. {0x12D20018, 0, 0, KNOWN_ZSTENCILDEPTH}, // Riva 128
  60. {0x10DE0020, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT
  61. {0x10DE0028, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT2
  62. {0x10DE0029, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT2 Ultra
  63. {0x10DE002C, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Vanta
  64. {0x10DE002D, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT2 Model 64
  65. {0x10DE00A0, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Aladdin TNT2
  66. {0x10DE0100, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV10 (GeForce)
  67. {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)
  68. {0x10DE0103, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV10 (Quadro)
  69. {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)
  70. {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)
  71. {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)
  72. {0x10DE0150, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV15 (GeForce2)
  73. {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)
  74. {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)
  75. {0x10DE0153, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV15 (Quadro2)
  76. {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)
  77. // 3DFX
  78. {0x121A0003, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_R5G6B5}, // Banshee
  79. {0x121A0005, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_R5G6B5}, // Voodoo3
  80. {0x121a0009, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A8R8G8B8}, // Voodoo4/5; same PCI-ID
  81. // ATI
  82. {0x10024742, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  83. {0x10024744, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  84. {0x10024749, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  85. {0x1002474D, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  86. {0x1002474E, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  87. {0x1002474F, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  88. {0x10024750, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  89. {0x10024752, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  90. {0x10024C42, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro (PCI)
  91. {0x10024C49, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro (PCI)
  92. {0x10024C4E, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  93. {0x10024C52, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  94. {0x10024C53, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
  95. {0x10024C60, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro LT
  96. {0x10024C4D, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X1R5G5B5}, // Rage Mobility AGP
  97. {0x10024C46, 0x0005000a, 0x00000404, 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
  98. {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
  99. {0x10024D46, 0x0005000a, 0x00000404, 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
  100. {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
  101. {0x10025046, 0x00050001, 0x098a0001, 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
  102. {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
  103. {0x10025245, 0x00050001, 0x098a0001, 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
  104. {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
  105. {0x10025246, 0x00050001, 0x098a0001, 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
  106. {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
  107. {0x1002524B, 0x00050001, 0x098a0001, 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
  108. {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
  109. {0x1002524C, 0x00050001, 0x098a0001, 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
  110. {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
  111. //New 128s for DX8.1:
  112. {0x10025041, 0x00050001, 0x098a0001, 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
  113. {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
  114. {0x10025042, 0x00050001, 0x098a0001, 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
  115. {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
  116. {0x10025043, 0x00050001, 0x098a0001, 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
  117. {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
  118. {0x10025044, 0x00050001, 0x098a0001, 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
  119. {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
  120. {0x10025045, 0x00050001, 0x098a0001, 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
  121. {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
  122. {0x10025047, 0x00050001, 0x098a0001, 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
  123. {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
  124. {0x10025048, 0x00050001, 0x098a0001, 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
  125. {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
  126. {0x10025049, 0x00050001, 0x098a0001, 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
  127. {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
  128. {0x1002504a, 0x00050001, 0x098a0001, 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
  129. {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
  130. {0x1002504b, 0x00050001, 0x098a0001, 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
  131. {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
  132. {0x1002504c, 0x00050001, 0x098a0001, 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
  133. {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
  134. {0x1002504d, 0x00050001, 0x098a0001, 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
  135. {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
  136. {0x1002504e, 0x00050001, 0x098a0001, 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
  137. {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
  138. {0x1002504f, 0x00050001, 0x098a0001, 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
  139. {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
  140. {0x10025050, 0x00050001, 0x098a0001, 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
  141. {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
  142. {0x10025051, 0x00050001, 0x098a0001, 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
  143. {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
  144. {0x10025052, 0x00050001, 0x098a0001, 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
  145. {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
  146. {0x10025053, 0x00050001, 0x098a0001, 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
  147. {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
  148. {0x10025054, 0x00050001, 0x098a0001, 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
  149. {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
  150. {0x10025055, 0x00050001, 0x098a0001, 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
  151. {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
  152. {0x10025056, 0x00050001, 0x098a0001, 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
  153. {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
  154. {0x10025057, 0x00050001, 0x098a0001, 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
  155. {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
  156. {0x10025058, 0x00050001, 0x098a0001, 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
  157. {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
  158. {0x10025345, 0x00050001, 0x098a0001, 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
  159. {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
  160. {0x10025346, 0x00050001, 0x098a0001, 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
  161. {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
  162. {0x10025347, 0x00050001, 0x098a0001, 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
  163. {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
  164. {0x10025348, 0x00050001, 0x098a0001, 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
  165. {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
  166. {0x1002534b, 0x00050001, 0x098a0001, 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
  167. {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
  168. {0x1002534c, 0x00050001, 0x098a0001, 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
  169. {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
  170. {0x1002534d, 0x00050001, 0x098a0001, 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
  171. {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
  172. {0x1002534e, 0x00050001, 0x098a0001, 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
  173. {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
  174. {0x10025446, 0x00050001, 0x098a0001, 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
  175. {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
  176. {0x1002544c, 0x00050001, 0x098a0001, 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
  177. {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
  178. {0x10025452, 0x00050001, 0x098a0001, 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
  179. {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
  180. {0x10025144, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
  181. {0x10025145, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
  182. {0x10025146, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
  183. {0x10025147, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
  184. // Intel
  185. {0x80867800, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Intel i740
  186. {0x80867123, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5}, // Intel 810
  187. {0x80867125, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5}, // Intel 810e
  188. {0x80861132, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5}, // Intel 815
  189. {0x80861A12, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Intel Timna
  190. // Matrox
  191. {0x102b0520, 0x0005000c, 0x000104b0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G200 PCI
  192. {0x102b0520, 0, 0, KNOWN_ZSTENCILDEPTH}, // G200 PCI
  193. {0x102b0521, 0x0005000c, 0x000104b0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G200 AGP
  194. {0x102b0521, 0, 0, KNOWN_ZSTENCILDEPTH}, // G200 AGP
  195. {0x102b0525, 0x0005000c, 0x000104b0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G400, G450
  196. {0x102b0525, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G400, G450
  197. // 3DLabs
  198. {0x3d3d0008, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH}, // 3DLabs Gamma
  199. {0x104c3d07, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8}, // Perm2
  200. {0x3d3d0009, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8}, // Perm2
  201. {0x3d3d000a, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Perm3
  202. {0x3d3d000a, 0x00050000, 0x08930001, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Perm3
  203. {0x3d3d000c, 0x00050000, 0x08930001, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Perm3
  204. // Videologic
  205. {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
  206. {0x104a0010, 0, 0, KNOWN_ZSTENCILDEPTH}, // PowerVR Kyro
  207. // S3
  208. {0x53338811, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge
  209. {0x53335631, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge
  210. {0x53338a01, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge DX/GX DX8.1
  211. {0x53338c01, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge MX DX8.1
  212. {0x53338a10, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge GX2 DX8.1
  213. {0x53338a20, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Savage3D
  214. {0x53338a22, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Savage4
  215. {0x53339102, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Savage2K
  216. {0x53338c10, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5}, // Savage MX DX8.1
  217. {0x53338c12, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5}, // Savage IX DX8.1
  218. {0x53338a25, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Savage Pro DX8.1
  219. {0x53338a26, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Savage Pro DX8.1
  220. // Trident
  221. {0x10239880, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Trident Blade 3D 9880
  222. {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
  223. {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
  224. {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
  225. {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
  226. // SiS
  227. {0x10390300, 0x0005000c, 0x0001044c, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 300
  228. {0x10390300, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5}, // SiS 300
  229. {0x10396326, 0x0005000c, 0x00010514, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5}, // SiS 6326
  230. {0x10396326, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER }, // SiS 6326
  231. {0x10395300, 0x0005000c, 0x0001044c, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 300
  232. {0x10395300, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5}, // SiS 300
  233. {0x10396300, 0x0005000c, 0x0001044c, 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
  234. {0x10396300, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5}, // SiS 6300
  235. {0x10390310, 0x0005000d, 0x0001035c, 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 310
  236. {0x10390315, 0x0005000d, 0x0001035c, 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 315
  237. {0x10390325, 0x0005000d, 0x000107d0, 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 325
  238. {0x10396325, 0x0005000d, 0x000107d0, 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
  239. {0x126f0720, 0, 0, KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A1R5G5B5} //Silicon Motion Lynx3DM
  240. };
  241. #define NUM_KNOWN_DEVICES (sizeof(gKnownDeviceList)/sizeof(KNOWNENTRY))
  242. #define RESPATH_D3D "Software\\Microsoft\\Direct3D"
  243. void InformDriverFreeAGP(HANDLE hDD);
  244. void InformDriverToDeferFrees(HANDLE hDD);
  245. void InformDriverAGPWorkaroundAware(HANDLE hDD);
  246. #ifdef DEBUG
  247. // Debug helper to indicate which surfaces are around
  248. //
  249. void DebugPrintSurfaceInfo(PDDSURFHANDLE pSurf)
  250. {
  251. switch (pSurf->Type)
  252. {
  253. case D3DRTYPE_SURFACE:
  254. DPF(0," D3DRTYPE_SURFACE");
  255. break;
  256. case D3DRTYPE_VOLUME:
  257. DPF(0," D3DRTYPE_VOLUME");
  258. break;
  259. case D3DRTYPE_TEXTURE:
  260. DPF(0," D3DRTYPE_TEXTURE");
  261. break;
  262. case D3DRTYPE_VOLUMETEXTURE:
  263. DPF(0," D3DRTYPE_VOLUMETEXTURE");
  264. break;
  265. case D3DRTYPE_CUBETEXTURE:
  266. DPF(0," D3DRTYPE_CUBETEXTURE");
  267. break;
  268. case D3DRTYPE_VERTEXBUFFER:
  269. DPF(0," D3DRTYPE_VERTEXBUFFER");
  270. break;
  271. case D3DRTYPE_INDEXBUFFER:
  272. DPF(0," D3DRTYPE_INDEXBUFFER");
  273. break;
  274. case D3DRTYPE_COMMANDBUFFER:
  275. DPF(0," D3DRTYPE_COMMANDBUFFER");
  276. break;
  277. default:
  278. DPF(0," UNKNOWN SURFACE TYPE");
  279. break;
  280. }
  281. } // DebugPrintSurfaceInfo
  282. #endif
  283. HRESULT MapLegacyResult(HRESULT in)
  284. {
  285. HRESULT hr;
  286. switch (in)
  287. {
  288. case DD_OK:
  289. hr = S_OK;
  290. break;
  291. case DDERR_OUTOFVIDEOMEMORY:
  292. hr = D3DERR_OUTOFVIDEOMEMORY;
  293. break;
  294. case DDERR_CURRENTLYNOTAVAIL:
  295. case DDERR_UNSUPPORTED:
  296. hr = D3DERR_NOTAVAILABLE;
  297. break;
  298. case DDERR_OUTOFMEMORY:
  299. hr = E_OUTOFMEMORY;
  300. break;
  301. default:
  302. hr = D3DERR_DRIVERINTERNALERROR;
  303. }
  304. return hr;
  305. }
  306. BOOL CanKnownDriverDoThis(PDDDEVICEHANDLE pDevice, DWORD Flag)
  307. {
  308. BOOL ret = FALSE;
  309. int i;
  310. if (pDevice->ForceFlagsOff & Flag)
  311. {
  312. return FALSE;
  313. }
  314. else if (pDevice->ForceFlagsOn & Flag)
  315. {
  316. return TRUE;
  317. }
  318. // Only drivers in our known good list can support lightweight
  319. // surfaces
  320. if (pDevice->PCIID == 0)
  321. {
  322. D3DADAPTER_IDENTIFIER8 DI;
  323. GetAdapterInfo(pDevice->szDeviceName, &DI, TRUE, TRUE, FALSE);
  324. pDevice->PCIID = (DI.VendorId << 16) | DI.DeviceId;
  325. pDevice->DriverVersionHigh = DI.DriverVersion.HighPart;
  326. pDevice->DriverVersionLow = DI.DriverVersion.LowPart;
  327. }
  328. for (i = 0; i < NUM_KNOWN_DEVICES; i++)
  329. {
  330. if ((gKnownDeviceList[i].PCIID == pDevice->PCIID) &&
  331. (gKnownDeviceList[i].Flags & Flag) &&
  332. ((pDevice->DriverVersionHigh > gKnownDeviceList[i].VersionMajor) ||
  333. ((pDevice->DriverVersionHigh == gKnownDeviceList[i].VersionMajor) &&
  334. (pDevice->DriverVersionLow >= gKnownDeviceList[i].VersionMinor))))
  335. {
  336. ret = TRUE;
  337. break;
  338. }
  339. }
  340. return ret;
  341. }
  342. BOOL FormatCompatibleWithDisplayFormat(
  343. PDDDEVICEHANDLE pDD,
  344. D3DFORMAT Format)
  345. {
  346. // The surface is compatible if formats match
  347. if (Format == pDD->DisplayFormatWithAlpha)
  348. return TRUE;
  349. return FALSE;
  350. }
  351. #undef DPF_MODNAME
  352. #define DPF_MODNAME "ReleaseDX7SurfaceHandle"
  353. void ReleaseDX7SurfaceHandle(HANDLE hDD, DWORD handle)
  354. {
  355. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  356. pDeviceHandle->SurfaceHandleList.dwList[handle].nextentry =
  357. pDeviceHandle->SurfaceHandleList.dwFreeList;
  358. pDeviceHandle->SurfaceHandleList.dwFreeList = handle;
  359. }
  360. #undef DPF_MODNAME
  361. #define DPF_MODNAME "FreeSurfaceObject"
  362. void FreeSurfaceObject (PDDSURFHANDLE pSurf)
  363. {
  364. DWORD dwRet = DDHAL_DRIVER_NOTHANDLED;
  365. // If the surface was created by a software driver, we need to call the
  366. // software driver to destroy it.
  367. if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  368. {
  369. // In a creation failure case, we may have not actually called the
  370. // driver/kernel to create this surface yet.
  371. // Release the kernel's handle first so that it
  372. // can finish up whatever it wants to before we free
  373. // the underlying memory
  374. if (pSurf->hSurface != 0)
  375. {
  376. OsThunkDdDeleteSurfaceObject(pSurf->hSurface);
  377. }
  378. // Now free the SW driver's object
  379. if (pSurf->dwFlags & DDSURF_CREATECOMPLETE)
  380. {
  381. dwRet = SwDDIDestroySurface (pSurf->pDevice, pSurf);
  382. }
  383. }
  384. else if (pSurf->hSurface != 0)
  385. {
  386. if (pSurf->Pool != D3DPOOL_SYSTEMMEM)
  387. {
  388. if ((pSurf->Type == D3DRTYPE_COMMANDBUFFER) ||
  389. (pSurf->Type == D3DRTYPE_VERTEXBUFFER) ||
  390. (pSurf->Type == D3DRTYPE_INDEXBUFFER) )
  391. {
  392. OsThunkDdDestroyD3DBuffer(pSurf->hSurface);
  393. }
  394. else
  395. {
  396. OsThunkDdDestroySurface(pSurf->hSurface, TRUE);
  397. }
  398. }
  399. OsThunkDdDeleteSurfaceObject(pSurf->hSurface);
  400. pSurf->hSurface = NULL;
  401. }
  402. if (pSurf->dwCookie)
  403. {
  404. // If CreateSurfaceEx was called on a sysmem surface, we need to tell
  405. // the driver. On NT, we only need to tell the software driver since
  406. // the kernel handles this for a real driver.
  407. if ((IS_SOFTWARE_DRIVER(pSurf->pDevice)) &&
  408. (pSurf->dwFlags & DDSURF_CREATECOMPLETE) &&
  409. (pSurf->Pool == D3DPOOL_SYSTEMMEM))
  410. {
  411. // DX7 called CreateSurfaceEx fpVidMem = 0 on each mipmap level
  412. // (even though it only creates it on the topmost level), so we
  413. // need to do the same to maintain driver compatibility.
  414. pSurf->pLcl->lpGbl->fpVidMem = 0;
  415. SwDDICreateSurfaceEx (pSurf->pDevice->pDD, pSurf->pLcl);
  416. }
  417. ReleaseDX7SurfaceHandle(pSurf->pDevice, pSurf->dwCookie);
  418. pSurf->dwCookie = 0;
  419. }
  420. if (pSurf->pLcl != NULL)
  421. {
  422. MemFree(pSurf->pLcl);
  423. pSurf->pLcl = NULL;
  424. }
  425. }
  426. #undef DPF_MODNAME
  427. #define DPF_MODNAME "CheckForDeviceLost"
  428. BOOL CheckForDeviceLost (HANDLE hDD)
  429. {
  430. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  431. PDDSURFHANDLE pSurf;
  432. DWORD Uniqueness = DdQueryDisplaySettingsUniqueness();
  433. if (!pDeviceHandle->bDeviceLost &&
  434. (Uniqueness != pDeviceHandle->DisplayUniqueness))
  435. {
  436. // If this is the first device to notice it is lost, then set
  437. // some state.
  438. if (InterlockedCompareExchange(&GlobalUniqueness, Uniqueness, GlobalUniqueness) != Uniqueness)
  439. {
  440. NumReadyDevices = 0;
  441. }
  442. pDeviceHandle->dwFlags &= ~DDDEVICE_READY;
  443. // The device has transitioned to the lost state, so we need
  444. // walk through the list and free the vidmem surfaces..
  445. pDeviceHandle->bDeviceLost = TRUE;
  446. pSurf = pDeviceHandle->pSurfList;
  447. while (pSurf != NULL)
  448. {
  449. if (IS_SURFACE_LOOSABLE(pSurf))
  450. {
  451. if (pSurf->LockRefCnt == 0)
  452. {
  453. FreeSurfaceObject(pSurf);
  454. }
  455. pSurf->fpVidMem = (ULONG_PTR) NULL;
  456. }
  457. pSurf = pSurf->pNext;
  458. }
  459. }
  460. return pDeviceHandle->bDeviceLost;
  461. }
  462. #undef DPF_MODNAME
  463. #define DPF_MODNAME "GetDX7SurfaceHandle"
  464. DWORD GetDX7SurfaceHandle (HANDLE hDD)
  465. {
  466. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  467. DWORD handle = pDeviceHandle->SurfaceHandleList.dwFreeList;
  468. if (0==handle)
  469. {
  470. // need to grow the dwList
  471. LPDDSURFACELISTENTRY newList;
  472. DWORD newsize;
  473. DWORD index;
  474. if (NULL != pDeviceHandle->SurfaceHandleList.dwList)
  475. {
  476. // old size(current dwFreeList) must not be zero
  477. DDASSERT(0 != pDeviceHandle->SurfaceHandleList.dwList[0].nextentry);
  478. // new dwFreeList is always gonna be the old dwList[0].nextentry
  479. newsize = pDeviceHandle->SurfaceHandleList.dwList[0].nextentry + LISTGROWSIZE;
  480. newList=(LPDDSURFACELISTENTRY)MemAlloc(newsize*sizeof(DDSURFACELISTENTRY));
  481. if (NULL == newList)
  482. {
  483. DPF_ERR("MemAlloc failure in GetSurfaceHandle(). Can't create new texture/surface/buffer.");
  484. return 0;
  485. }
  486. pDeviceHandle->SurfaceHandleList.dwFreeList =
  487. pDeviceHandle->SurfaceHandleList.dwList[0].nextentry;
  488. memcpy((LPVOID)newList,(LPVOID)pDeviceHandle->SurfaceHandleList.dwList,
  489. pDeviceHandle->SurfaceHandleList.dwList[0].nextentry*sizeof(DDSURFACELISTENTRY));
  490. MemFree(pDeviceHandle->SurfaceHandleList.dwList);
  491. }
  492. else
  493. {
  494. newsize = LISTGROWSIZE;
  495. newList=(LPDDSURFACELISTENTRY)MemAlloc(newsize*sizeof(DDSURFACELISTENTRY));
  496. if (NULL == newList)
  497. {
  498. DPF_ERR("MemAlloc failure in GetSurfaceHandle(). Can't create new texture/surface/buffer");
  499. return 0;
  500. }
  501. // start from one as we don't want 0 as a valid handle
  502. pDeviceHandle->SurfaceHandleList.dwFreeList = 1;
  503. }
  504. pDeviceHandle->SurfaceHandleList.dwList=newList;
  505. pDeviceHandle->SurfaceHandleList.dwList[0].nextentry=newsize;
  506. for (index = pDeviceHandle->SurfaceHandleList.dwFreeList;
  507. index < newsize - 1;
  508. index++)
  509. {
  510. newList[index].nextentry=index+1;
  511. }
  512. // indicate end of new FreeList
  513. newList[newsize-1].nextentry=0;
  514. // now pop up one and assign it to handle
  515. handle=pDeviceHandle->SurfaceHandleList.dwFreeList;
  516. }
  517. // handle slot is avialable so just remove it from freeList
  518. pDeviceHandle->SurfaceHandleList.dwFreeList =
  519. pDeviceHandle->SurfaceHandleList.dwList[handle].nextentry;
  520. #if DBG
  521. pDeviceHandle->SurfaceHandleList.dwList[handle].nextentry=0xDEADBEEF;
  522. #endif
  523. pDeviceHandle->SurfaceHandleList.dwList[handle].dwFlags=0; //mark it's new
  524. pDeviceHandle->SurfaceHandleList.dwList[handle].lpSurface=NULL;
  525. DDASSERT (handle > 0);
  526. DDASSERT (handle < pDeviceHandle->SurfaceHandleList.dwList[0].nextentry);
  527. return handle;
  528. }
  529. /*****************************Private*Routine******************************\
  530. * DdConvertToOldFormat
  531. *
  532. * History:
  533. * 3-Nov-1999 -by- Scott MacDonald [smac]
  534. * Wrote it.
  535. \**************************************************************************/
  536. #undef DPF_MODNAME
  537. #define DPF_MODNAME "ConvertToOldFormat"
  538. void ConvertToOldFormat(LPDDPIXELFORMAT pOldFormat, D3DFORMAT NewFormat)
  539. {
  540. // Zero out the format to avoid missing
  541. // cases where it isn't initialized right
  542. ZeroMemory(pOldFormat, sizeof(*pOldFormat));
  543. // Set Size
  544. pOldFormat->dwSize = sizeof(DDPIXELFORMAT);
  545. // Convert away
  546. if (HIWORD((DWORD)NewFormat))
  547. {
  548. pOldFormat->dwFlags = DDPF_FOURCC;
  549. pOldFormat->dwFourCC = (DWORD)NewFormat;
  550. return;
  551. }
  552. switch (NewFormat)
  553. {
  554. case D3DFMT_R8G8B8:
  555. pOldFormat->dwFlags = DDPF_RGB;
  556. pOldFormat->dwRBitMask = 0x00ff0000;
  557. pOldFormat->dwGBitMask = 0x0000ff00;
  558. pOldFormat->dwBBitMask = 0x000000ff;
  559. pOldFormat->dwRGBBitCount = 24;
  560. break;
  561. case D3DFMT_A8R8G8B8:
  562. pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
  563. pOldFormat->dwRGBAlphaBitMask = 0xFF000000;
  564. pOldFormat->dwRBitMask = 0x00ff0000;
  565. pOldFormat->dwGBitMask = 0x0000ff00;
  566. pOldFormat->dwBBitMask = 0x000000ff;
  567. pOldFormat->dwRGBBitCount = 32;
  568. break;
  569. case D3DFMT_X8R8G8B8:
  570. pOldFormat->dwFlags = DDPF_RGB;
  571. pOldFormat->dwRBitMask = 0x00ff0000;
  572. pOldFormat->dwGBitMask = 0x0000ff00;
  573. pOldFormat->dwBBitMask = 0x000000ff;
  574. pOldFormat->dwRGBBitCount = 32;
  575. break;
  576. case D3DFMT_R5G6B5:
  577. pOldFormat->dwFlags = DDPF_RGB;
  578. pOldFormat->dwRBitMask = 0x0000f800;
  579. pOldFormat->dwGBitMask = 0x000007e0;
  580. pOldFormat->dwBBitMask = 0x0000001f;
  581. pOldFormat->dwRGBBitCount = 16;
  582. break;
  583. case D3DFMT_X1R5G5B5:
  584. pOldFormat->dwFlags = DDPF_RGB;
  585. pOldFormat->dwRBitMask = 0x00007c00;
  586. pOldFormat->dwGBitMask = 0x000003e0;
  587. pOldFormat->dwBBitMask = 0x0000001f;
  588. pOldFormat->dwRGBBitCount = 16;
  589. break;
  590. case D3DFMT_A1R5G5B5:
  591. pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
  592. pOldFormat->dwRGBAlphaBitMask = 0x00008000;
  593. pOldFormat->dwRBitMask = 0x00007c00;
  594. pOldFormat->dwGBitMask = 0x000003e0;
  595. pOldFormat->dwBBitMask = 0x0000001f;
  596. pOldFormat->dwRGBBitCount = 16;
  597. break;
  598. case D3DFMT_A4R4G4B4:
  599. pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
  600. pOldFormat->dwRGBAlphaBitMask = 0x0000f000;
  601. pOldFormat->dwRBitMask = 0x00000f00;
  602. pOldFormat->dwGBitMask = 0x000000f0;
  603. pOldFormat->dwBBitMask = 0x0000000f;
  604. pOldFormat->dwRGBBitCount = 16;
  605. break;
  606. case D3DFMT_X4R4G4B4:
  607. pOldFormat->dwFlags = DDPF_RGB;
  608. pOldFormat->dwRBitMask = 0x00000f00;
  609. pOldFormat->dwGBitMask = 0x000000f0;
  610. pOldFormat->dwBBitMask = 0x0000000f;
  611. pOldFormat->dwRGBBitCount = 16;
  612. break;
  613. case D3DFMT_R3G3B2:
  614. pOldFormat->dwFlags = DDPF_RGB;
  615. pOldFormat->dwRBitMask = 0x000000e0;
  616. pOldFormat->dwGBitMask = 0x0000001c;
  617. pOldFormat->dwBBitMask = 0x00000003;
  618. pOldFormat->dwRGBBitCount = 8;
  619. break;
  620. case D3DFMT_A8R3G3B2:
  621. pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
  622. pOldFormat->dwRGBAlphaBitMask = 0x0000FF00;
  623. pOldFormat->dwRBitMask = 0x000000e0;
  624. pOldFormat->dwGBitMask = 0x0000001c;
  625. pOldFormat->dwBBitMask = 0x00000003;
  626. pOldFormat->dwRGBBitCount = 16;
  627. break;
  628. case D3DFMT_A8P8:
  629. pOldFormat->dwFlags = DDPF_RGB |
  630. DDPF_ALPHAPIXELS |
  631. DDPF_PALETTEINDEXED8;
  632. pOldFormat->dwRGBAlphaBitMask = 0x0000FF00;
  633. pOldFormat->dwRGBBitCount = 16;
  634. break;
  635. case D3DFMT_P8:
  636. pOldFormat->dwFlags = DDPF_RGB |
  637. DDPF_PALETTEINDEXED8;
  638. pOldFormat->dwRGBBitCount = 8;
  639. break;
  640. case D3DFMT_L8:
  641. pOldFormat->dwFlags = DDPF_LUMINANCE;
  642. pOldFormat->dwLuminanceBitMask = 0x000000FF;
  643. pOldFormat->dwLuminanceBitCount = 8;
  644. break;
  645. case D3DFMT_A8L8:
  646. pOldFormat->dwFlags = DDPF_LUMINANCE |
  647. DDPF_ALPHAPIXELS;
  648. pOldFormat->dwLuminanceAlphaBitMask = 0x0000FF00;
  649. pOldFormat->dwLuminanceBitMask = 0x000000FF;
  650. pOldFormat->dwLuminanceBitCount = 16;
  651. break;
  652. case D3DFMT_A4L4:
  653. pOldFormat->dwFlags = DDPF_LUMINANCE |
  654. DDPF_ALPHAPIXELS;
  655. pOldFormat->dwLuminanceAlphaBitMask = 0x000000F0;
  656. pOldFormat->dwLuminanceBitMask = 0x0000000F;
  657. pOldFormat->dwLuminanceBitCount = 8;
  658. break;
  659. case D3DFMT_V8U8:
  660. pOldFormat->dwFlags = DDPF_BUMPDUDV;
  661. pOldFormat->dwBumpDvBitMask = 0x0000FF00;
  662. pOldFormat->dwBumpDuBitMask = 0x000000FF;
  663. pOldFormat->dwBumpBitCount = 16;
  664. break;
  665. case D3DFMT_L6V5U5:
  666. pOldFormat->dwFlags = DDPF_BUMPDUDV |
  667. DDPF_BUMPLUMINANCE;
  668. pOldFormat->dwBumpLuminanceBitMask = 0x0000FC00;
  669. pOldFormat->dwBumpDvBitMask = 0x000003E0;
  670. pOldFormat->dwBumpDuBitMask = 0x0000001F;
  671. pOldFormat->dwBumpBitCount = 16;
  672. break;
  673. case D3DFMT_X8L8V8U8:
  674. pOldFormat->dwFlags = DDPF_BUMPDUDV |
  675. DDPF_BUMPLUMINANCE;
  676. pOldFormat->dwBumpLuminanceBitMask = 0x00FF0000;
  677. pOldFormat->dwBumpDvBitMask = 0x0000FF00;
  678. pOldFormat->dwBumpDuBitMask = 0x000000FF;
  679. pOldFormat->dwBumpBitCount = 32;
  680. break;
  681. case D3DFMT_A8:
  682. pOldFormat->dwFlags = DDPF_ALPHA;
  683. pOldFormat->dwAlphaBitDepth = 8;
  684. break;
  685. case D3DFMT_D16:
  686. case D3DFMT_D16_LOCKABLE:
  687. pOldFormat->dwFlags = DDPF_ZBUFFER;
  688. pOldFormat->dwZBufferBitDepth = 16;
  689. pOldFormat->dwZBitMask = 0xFFFF;
  690. pOldFormat->dwStencilBitDepth = 0;
  691. pOldFormat->dwStencilBitMask = 0;
  692. break;
  693. case D3DFMT_D32:
  694. pOldFormat->dwFlags = DDPF_ZBUFFER;
  695. pOldFormat->dwZBufferBitDepth = 32;
  696. pOldFormat->dwZBitMask = 0xFFFFFFFF;
  697. pOldFormat->dwStencilBitDepth = 0;
  698. pOldFormat->dwStencilBitMask = 0;
  699. break;
  700. case D3DFMT_D15S1:
  701. pOldFormat->dwFlags = DDPF_ZBUFFER |
  702. DDPF_STENCILBUFFER;
  703. pOldFormat->dwZBufferBitDepth = 16;
  704. pOldFormat->dwZBitMask = 0xFFFE;
  705. pOldFormat->dwStencilBitDepth = 1;
  706. pOldFormat->dwStencilBitMask = 0x0001;
  707. break;
  708. case D3DFMT_D24S8:
  709. pOldFormat->dwFlags = DDPF_ZBUFFER |
  710. DDPF_STENCILBUFFER;
  711. pOldFormat->dwZBufferBitDepth = 32;
  712. pOldFormat->dwZBitMask = 0xFFFFFF00;
  713. pOldFormat->dwStencilBitDepth = 8;
  714. pOldFormat->dwStencilBitMask = 0xFF;
  715. break;
  716. case D3DFMT_S1D15:
  717. pOldFormat->dwFlags = DDPF_ZBUFFER |
  718. DDPF_STENCILBUFFER;
  719. pOldFormat->dwZBufferBitDepth = 16;
  720. pOldFormat->dwZBitMask = 0x7FFF;
  721. pOldFormat->dwStencilBitDepth = 1;
  722. pOldFormat->dwStencilBitMask = 0x8000;
  723. break;
  724. case D3DFMT_S8D24:
  725. pOldFormat->dwFlags = DDPF_ZBUFFER |
  726. DDPF_STENCILBUFFER;
  727. pOldFormat->dwZBufferBitDepth = 32;
  728. pOldFormat->dwZBitMask = 0x00FFFFFF;
  729. pOldFormat->dwStencilBitDepth = 8;
  730. pOldFormat->dwStencilBitMask = 0xFF000000;
  731. break;
  732. case D3DFMT_X8D24:
  733. pOldFormat->dwFlags = DDPF_ZBUFFER;
  734. pOldFormat->dwZBufferBitDepth = 32;
  735. pOldFormat->dwZBitMask = 0x00FFFFFF;
  736. pOldFormat->dwStencilBitDepth = 0;
  737. pOldFormat->dwStencilBitMask = 0x00000000;
  738. break;
  739. case D3DFMT_D24X8:
  740. pOldFormat->dwFlags = DDPF_ZBUFFER;
  741. pOldFormat->dwZBufferBitDepth = 32;
  742. pOldFormat->dwZBitMask = 0xFFFFFF00;
  743. pOldFormat->dwStencilBitDepth = 0;
  744. pOldFormat->dwStencilBitMask = 0x00000000;
  745. break;
  746. case D3DFMT_D24X4S4:
  747. pOldFormat->dwFlags = DDPF_ZBUFFER |
  748. DDPF_STENCILBUFFER;
  749. pOldFormat->dwZBufferBitDepth = 32;
  750. pOldFormat->dwZBitMask = 0xFFFFFF00;
  751. pOldFormat->dwStencilBitDepth = 4;
  752. pOldFormat->dwStencilBitMask = 0x0000000F;
  753. break;
  754. case D3DFMT_X4S4D24:
  755. pOldFormat->dwFlags = DDPF_ZBUFFER |
  756. DDPF_STENCILBUFFER;
  757. pOldFormat->dwZBufferBitDepth = 32;
  758. pOldFormat->dwZBitMask = 0x00FFFFFF;
  759. pOldFormat->dwStencilBitDepth = 4;
  760. pOldFormat->dwStencilBitMask = 0x0F000000;
  761. break;
  762. default:
  763. // All other formats are treated as a
  764. // FOURCC
  765. pOldFormat->dwFlags = DDPF_FOURCC;
  766. pOldFormat->dwFourCC = (DWORD)NewFormat;
  767. break;
  768. }
  769. return;
  770. }
  771. /*****************************Private*Routine******************************\
  772. * InitSurfaceStructures
  773. *
  774. * History:
  775. * 06-Dec-1999 -by- Scott MacDonald [smac]
  776. * Wrote it.
  777. \**************************************************************************/
  778. #undef DPF_MODNAME
  779. #define DPF_MODNAME "InitSurfaceStructure"
  780. void InitSurfaceStructures(
  781. PD3D8_CREATESURFACEDATA pCreateSurface,
  782. DD_SURFACE_LOCAL* pDDSurfaceLocal,
  783. DD_SURFACE_GLOBAL* pDDSurfaceGlobal,
  784. DD_SURFACE_MORE* pDDSurfaceMore
  785. )
  786. {
  787. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pCreateSurface->hDD;
  788. DWORD i;
  789. DWORD j;
  790. DWORD dwBit;
  791. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  792. {
  793. // Make sure there's always a valid pixel format for the surface:
  794. if ((pCreateSurface->Format != D3DFMT_UNKNOWN) &&
  795. (pCreateSurface->Format != D3DFMT_VERTEXDATA) &&
  796. (pCreateSurface->Format != D3DFMT_INDEX16) &&
  797. (pCreateSurface->Format != D3DFMT_INDEX32))
  798. {
  799. pDDSurfaceLocal[i].dwFlags |= DDRAWISURF_HASPIXELFORMAT;
  800. // For non-textures, we want to promote X8R8G8B8 to A8R8G8B8 in some cases;
  801. // this allows things like RTs and Backbuffers to get created matching the
  802. // primary which is more consistent with typical DX7 usage.
  803. if (FormatCompatibleWithDisplayFormat(pDevice, (D3DFORMAT)pCreateSurface->Format) &&
  804. (pCreateSurface->Type == D3DRTYPE_SURFACE))
  805. {
  806. ConvertToOldFormat(&pDDSurfaceGlobal[i].ddpfSurface, pDevice->DisplayFormatWithAlpha);
  807. }
  808. else
  809. {
  810. ConvertToOldFormat(&pDDSurfaceGlobal[i].ddpfSurface, (D3DFORMAT)pCreateSurface->Format);
  811. }
  812. }
  813. // Setup width/height first
  814. pDDSurfaceGlobal[i].wWidth = pCreateSurface->pSList[i].cpWidth;
  815. pDDSurfaceGlobal[i].wHeight = pCreateSurface->pSList[i].cpHeight;
  816. //dwCaps3==1 means 1 sample per pixel.
  817. pDDSurfaceMore[i].ddsCapsEx.dwCaps3 = DDSCAPS3_MULTISAMPLE_MASK & (DWORD) pCreateSurface->MultiSampleType;
  818. if (pCreateSurface->dwUsage & D3DUSAGE_ALPHACHANNEL)
  819. {
  820. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_ENABLEALPHACHANNEL;
  821. }
  822. switch (pCreateSurface->Type)
  823. {
  824. case D3DRTYPE_SURFACE:
  825. // Surfaces come in three general flavors:
  826. // - Primary flip chains
  827. // - Z buffers
  828. // - OffscreenPlain (RenderTargets or just sys-mem stuff)
  829. //
  830. // Textures are a different resource type
  831. if (pCreateSurface->dwUsage & D3DUSAGE_PRIMARYSURFACE)
  832. {
  833. // If we aren't creating a primary flip chain, then we
  834. // don't have to do much here.
  835. if (pCreateSurface->dwSCnt == 1)
  836. {
  837. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
  838. }
  839. else
  840. {
  841. if (i == 0)
  842. {
  843. // This is the front buffer
  844. pDDSurfaceLocal[i].ddsCaps.dwCaps |=
  845. DDSCAPS_PRIMARYSURFACE |
  846. DDSCAPS_VISIBLE |
  847. DDSCAPS_FRONTBUFFER;
  848. }
  849. else
  850. {
  851. // This is a back buffer
  852. pDDSurfaceLocal[i].ddsCaps.dwCaps |=
  853. DDSCAPS_BACKBUFFER;
  854. }
  855. // All surfaces in the primary chain get these caps
  856. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_3DDEVICE;
  857. // We also get a CreateEx handle for all surfaces in the
  858. // chain, but not if we're running w/ a software driver.
  859. if (((PDDDEVICEHANDLE)pCreateSurface->hDD)->pDD == NULL)
  860. {
  861. pDDSurfaceMore[i].dwSurfaceHandle = GetDX7SurfaceHandle(pCreateSurface->hDD);
  862. }
  863. }
  864. }
  865. else if (pCreateSurface->dwUsage & D3DUSAGE_DEPTHSTENCIL)
  866. {
  867. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  868. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_ZBUFFER;
  869. pDDSurfaceMore[i].dwSurfaceHandle = GetDX7SurfaceHandle(pCreateSurface->hDD);
  870. }
  871. else
  872. {
  873. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
  874. }
  875. break;
  876. case D3DRTYPE_VOLUME:
  877. // We don't create stand-alone volumes
  878. DDASSERT(FALSE);
  879. break;
  880. case D3DRTYPE_TEXTURE:
  881. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  882. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
  883. //mipmaps are only DDI-level mipmaps if they're more than one level
  884. if (pCreateSurface->dwSCnt>1)
  885. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
  886. if (i > 0)
  887. {
  888. // Mark non-top levels as being a sub-level
  889. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
  890. }
  891. if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
  892. {
  893. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
  894. }
  895. pDDSurfaceMore[i].dwSurfaceHandle = GetDX7SurfaceHandle(pCreateSurface->hDD);
  896. break;
  897. case D3DRTYPE_VOLUMETEXTURE:
  898. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  899. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
  900. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_VOLUME;
  901. pDDSurfaceMore[i].ddsCapsEx.dwCaps4 =
  902. MAKELONG((WORD)(pCreateSurface->pSList[i].cpDepth),0);
  903. if (i > 0)
  904. {
  905. // Mark non-top levels as being a sub-level
  906. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
  907. }
  908. if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
  909. {
  910. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
  911. }
  912. pDDSurfaceMore[i].dwSurfaceHandle = GetDX7SurfaceHandle(pCreateSurface->hDD);
  913. break;
  914. case D3DRTYPE_CUBETEXTURE:
  915. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  916. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
  917. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_CUBEMAP;
  918. pDDSurfaceMore[i].dwSurfaceHandle = GetDX7SurfaceHandle(pCreateSurface->hDD);
  919. //cubemaps are only DDI-level mipmaps if they're more than one level
  920. if (pCreateSurface->dwSCnt>6)
  921. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
  922. // DX8 only supports creation of all faces
  923. {
  924. DWORD dwOrderedFaces[6] = {
  925. DDSCAPS2_CUBEMAP_POSITIVEX,
  926. DDSCAPS2_CUBEMAP_NEGATIVEX,
  927. DDSCAPS2_CUBEMAP_POSITIVEY,
  928. DDSCAPS2_CUBEMAP_NEGATIVEY,
  929. DDSCAPS2_CUBEMAP_POSITIVEZ,
  930. DDSCAPS2_CUBEMAP_NEGATIVEZ
  931. };
  932. int MipLevels;
  933. MipLevels = pCreateSurface->dwSCnt/6; //since all faces are always present in DX8
  934. DDASSERT(MipLevels>=1);
  935. //the first n (where n is mip depth) faces are +x, etc.
  936. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= dwOrderedFaces[i/MipLevels];
  937. //every MipLevels'th surface is a top-level face,
  938. if (i % MipLevels)
  939. {
  940. // Mark non-top levels as being a sub-level
  941. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
  942. }
  943. if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
  944. {
  945. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
  946. }
  947. }
  948. break;
  949. case D3DRTYPE_IMAGESURFACE:
  950. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  951. // Image surfaces are marked as textures since they have the
  952. // greatest flexibility for formats. But they don't get
  953. // a CreateSurfaceEx handle since they are never passed to
  954. // a driver.
  955. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
  956. break;
  957. case D3DRTYPE_COMMANDBUFFER:
  958. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  959. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_EXECUTEBUFFER;
  960. pDDSurfaceMore[i].dwSurfaceHandle = GetDX7SurfaceHandle(pCreateSurface->hDD);
  961. DDASSERT((pCreateSurface->dwUsage & D3DUSAGE_INTERNALBUFFER) == 0);
  962. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_COMMANDBUFFER;
  963. pDDSurfaceGlobal[i].dwLinearSize = pDDSurfaceGlobal[i].wWidth;
  964. break;
  965. case D3DRTYPE_VERTEXBUFFER:
  966. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  967. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_EXECUTEBUFFER;
  968. if (!(pCreateSurface->dwUsage & D3DUSAGE_INTERNALBUFFER))
  969. {
  970. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_VERTEXBUFFER;
  971. }
  972. if (pDevice->DriverLevel >= 8)
  973. {
  974. if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
  975. {
  976. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
  977. }
  978. else
  979. {
  980. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_HINTSTATIC;
  981. }
  982. }
  983. pDDSurfaceMore[i].dwSurfaceHandle = GetDX7SurfaceHandle(pCreateSurface->hDD);
  984. pDDSurfaceGlobal[i].dwLinearSize = pDDSurfaceGlobal[i].wWidth;
  985. break;
  986. case D3DRTYPE_INDEXBUFFER:
  987. DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
  988. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_EXECUTEBUFFER;
  989. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_INDEXBUFFER;
  990. if (pDevice->DriverLevel >= 8)
  991. {
  992. if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
  993. {
  994. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
  995. }
  996. else
  997. {
  998. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_HINTSTATIC;
  999. }
  1000. }
  1001. pDDSurfaceMore[i].dwSurfaceHandle = GetDX7SurfaceHandle(pCreateSurface->hDD);
  1002. pDDSurfaceGlobal[i].dwLinearSize = pDDSurfaceGlobal[i].wWidth;
  1003. break;
  1004. }
  1005. if (pCreateSurface->dwUsage & D3DUSAGE_RENDERTARGET)
  1006. {
  1007. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_3DDEVICE;
  1008. if (pDDSurfaceMore[i].dwSurfaceHandle == 0)
  1009. {
  1010. pDDSurfaceMore[i].dwSurfaceHandle = GetDX7SurfaceHandle(pCreateSurface->hDD);
  1011. }
  1012. }
  1013. if (pCreateSurface->dwUsage & D3DUSAGE_DEPTHSTENCIL)
  1014. {
  1015. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_ZBUFFER;
  1016. }
  1017. if (pDevice->DriverLevel >= 8)
  1018. {
  1019. if (pCreateSurface->dwUsage & D3DUSAGE_LOADONCE)
  1020. {
  1021. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_OPAQUE;
  1022. }
  1023. if (pCreateSurface->dwUsage & D3DUSAGE_WRITEONLY)
  1024. {
  1025. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_WRITEONLY;
  1026. }
  1027. if (!(pCreateSurface->dwUsage & D3DUSAGE_LOCK) &&
  1028. !(pCreateSurface->dwUsage & D3DUSAGE_LOADONCE))
  1029. {
  1030. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_NOTUSERLOCKABLE;
  1031. }
  1032. if (pCreateSurface->dwUsage & D3DUSAGE_DISCARD)
  1033. {
  1034. DDASSERT(pCreateSurface->Type != D3DRTYPE_TEXTURE);
  1035. DDASSERT(pCreateSurface->Type != D3DRTYPE_CUBETEXTURE);
  1036. DDASSERT(pCreateSurface->Type != D3DRTYPE_VOLUMETEXTURE);
  1037. DDASSERT(pCreateSurface->Type != D3DRTYPE_VOLUME);
  1038. DDASSERT(pCreateSurface->Type != D3DRTYPE_VERTEXBUFFER);
  1039. DDASSERT(pCreateSurface->Type != D3DRTYPE_INDEXBUFFER);
  1040. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_DISCARDBACKBUFFER;
  1041. }
  1042. if (pCreateSurface->dwUsage & D3DUSAGE_POINTS)
  1043. {
  1044. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_POINTS;
  1045. }
  1046. if (pCreateSurface->dwUsage & D3DUSAGE_RTPATCHES)
  1047. {
  1048. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_RTPATCHES;
  1049. }
  1050. if (pCreateSurface->dwUsage & D3DUSAGE_NPATCHES)
  1051. {
  1052. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_NPATCHES;
  1053. }
  1054. }
  1055. else // Pre-DX8 driver
  1056. {
  1057. // We allow LOADONCE through only for textures
  1058. if (pCreateSurface->Type == D3DRTYPE_TEXTURE ||
  1059. pCreateSurface->Type == D3DRTYPE_CUBETEXTURE ||
  1060. pCreateSurface->Type == D3DRTYPE_VOLUMETEXTURE)
  1061. {
  1062. if (pCreateSurface->dwUsage & D3DUSAGE_LOADONCE)
  1063. {
  1064. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_OPAQUE;
  1065. }
  1066. }
  1067. // We allow WRITEONLY through only for VBs
  1068. if (pCreateSurface->Type == D3DRTYPE_VERTEXBUFFER)
  1069. {
  1070. if (pCreateSurface->dwUsage & D3DUSAGE_WRITEONLY)
  1071. {
  1072. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_WRITEONLY;
  1073. }
  1074. }
  1075. }
  1076. switch (pCreateSurface->Pool)
  1077. {
  1078. case D3DPOOL_LOCALVIDMEM:
  1079. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
  1080. break;
  1081. case D3DPOOL_NONLOCALVIDMEM:
  1082. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
  1083. break;
  1084. case D3DPOOL_SYSTEMMEM:
  1085. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
  1086. break;
  1087. case D3DPOOL_MANAGED:
  1088. pDDSurfaceLocal[i].dwFlags |= DDRAWISURF_DRIVERMANAGED;
  1089. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
  1090. pDDSurfaceMore[i].ddsCapsEx.dwCaps2 |= DDSCAPS2_TEXTUREMANAGE;
  1091. break;
  1092. case D3DPOOL_DEFAULT:
  1093. pCreateSurface->Pool = D3DPOOL_LOCALVIDMEM;
  1094. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
  1095. break;
  1096. default:
  1097. /* Unknown Pool?? */
  1098. DDASSERT(FALSE);
  1099. break;
  1100. }
  1101. }
  1102. }
  1103. /*****************************Private*Routine******************************\
  1104. * SelectAttachmentSurface
  1105. *
  1106. * Returns an index into the surface creation list that indicates which
  1107. * surface this surface should be attached to. For mipmap sublevels this is
  1108. * always the preceding surface. For cubemaps, each face attaches to the
  1109. * root face (element 0).
  1110. *
  1111. * History:
  1112. * 21-Mar-2000 -by- Jeff Noyle [jeffno]
  1113. * Wrote it.
  1114. \**************************************************************************/
  1115. #undef DPF_MODNAME
  1116. #define DPF_MODNAME "SelectAttachmentSurface"
  1117. UINT SelectAttachmentSurface(
  1118. PD3D8_CREATESURFACEDATA pCreateSurface,
  1119. UINT iThis)
  1120. {
  1121. //We should never be called to find the attachment from the root face.
  1122. DDASSERT( iThis > 0);
  1123. if ((pCreateSurface->Type == D3DRTYPE_CUBETEXTURE) &&
  1124. ((iThis % (pCreateSurface->dwSCnt/6)) == 0) //which means we're looking at a top-level face
  1125. )
  1126. {
  1127. //... so we attach this face to the root
  1128. return 0;
  1129. }
  1130. else
  1131. {
  1132. // nope its just a mip sublevel, so we attach to the previous
  1133. return iThis-1;
  1134. }
  1135. }
  1136. /*****************************Private*Routine******************************\
  1137. * CreateVidMemSurface
  1138. *
  1139. * History:
  1140. * 06-Dec-1999 -by- Scott MacDonald [smac]
  1141. * Wrote it.
  1142. \**************************************************************************/
  1143. #undef DPF_MODNAME
  1144. #define DPF_MODNAME "CreateVidMemSurface"
  1145. HRESULT
  1146. CreateVidMemSurface(
  1147. PD3D8_CREATESURFACEDATA pCreateSurface,
  1148. DD_SURFACE_LOCAL* pDDSurfaceLocal,
  1149. DD_SURFACE_GLOBAL* pDDSurfaceGlobal,
  1150. DD_SURFACE_MORE* pDDSurfaceMore,
  1151. HANDLE* phInSurface,
  1152. HANDLE* phOutSurface,
  1153. BOOL bIsLost
  1154. )
  1155. {
  1156. DDSURFACEDESC2 SurfaceDesc;
  1157. DD_CREATESURFACEDATA CreateData7;
  1158. DWORD i;
  1159. DWORD j;
  1160. BOOL bRet;
  1161. DDSURFHANDLE* pSurf;
  1162. DD_CANCREATESURFACEDATA CanCreateData;
  1163. DEFERREDCREATE* pDefCreate;
  1164. if (DDSCAPS_EXECUTEBUFFER & pDDSurfaceLocal[0].ddsCaps.dwCaps)
  1165. {
  1166. if (!(DDDEVICE_SUPPORTD3DBUF &
  1167. ((PDDDEVICEHANDLE)pCreateSurface->hDD)->dwFlags)
  1168. )
  1169. {
  1170. return E_FAIL;
  1171. }
  1172. }
  1173. // If the device is lost, we don't want to allocate vidmem or call the
  1174. // kernel at this point (the surface will be released soon anyway).
  1175. if (bIsLost)
  1176. {
  1177. DeviceLost:
  1178. DDASSERT(pCreateSurface->bReUse == FALSE);
  1179. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  1180. {
  1181. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  1182. pDDSurfaceMore[i].dwSurfaceHandle = 0;
  1183. // There is a chance that the app may call Lock at some point,
  1184. // in which case we have to allocate a buffer that they can write
  1185. // to. Allocating the buffer now is a bit wasteful, but if we
  1186. // allocate it at Lock time the allocation may fail and I'm
  1187. // guessing that apps will handle create surface failures better
  1188. // than they will Lock failures, so we will do the allocation now.
  1189. pDDSurfaceGlobal[i].lPitch = pCreateSurface->pSList[i].cpWidth * 8;
  1190. pDDSurfaceGlobal[i].dwLinearSize =
  1191. pDDSurfaceGlobal[i].lPitch;
  1192. if ((pCreateSurface->Type == D3DRTYPE_VOLUME) ||
  1193. (pCreateSurface->Type == D3DRTYPE_VOLUMETEXTURE))
  1194. {
  1195. pSurf->lSlicePitch = pDDSurfaceGlobal[i].lPitch *
  1196. pCreateSurface->pSList[i].cpHeight;
  1197. pDDSurfaceGlobal[i].fpVidMem = (ULONG_PTR)
  1198. MemAlloc(pSurf->lSlicePitch *
  1199. pCreateSurface->pSList[i].cpDepth);
  1200. }
  1201. else
  1202. {
  1203. pDDSurfaceGlobal[i].fpVidMem = (ULONG_PTR)
  1204. MemAlloc(pDDSurfaceGlobal[i].lPitch *
  1205. pCreateSurface->pSList[i].cpHeight);
  1206. }
  1207. if (pDDSurfaceGlobal[i].fpVidMem == (ULONG_PTR) NULL)
  1208. {
  1209. for (j = 0; j < i; j++)
  1210. {
  1211. MemFree((void*)pDDSurfaceGlobal[j].fpVidMem);
  1212. }
  1213. return E_OUTOFMEMORY;
  1214. }
  1215. pSurf->dwFlags |= DDSURF_SYSMEMALLOCATED;
  1216. }
  1217. // If the surface is driver managed, we save the creation info so that
  1218. // we can retry the creation at reset time
  1219. if (pDDSurfaceLocal[0].dwFlags & DDRAWISURF_DRIVERMANAGED)
  1220. {
  1221. pDefCreate = (PDEFERREDCREATE)MemAlloc(sizeof(DEFERREDCREATE));
  1222. if (pDefCreate == NULL)
  1223. {
  1224. // Cleanup stuff that we allocated above
  1225. for (i = 0; i < pCreateSurface->dwSCnt; ++i)
  1226. {
  1227. MemFree((void*)pDDSurfaceGlobal[i].fpVidMem);
  1228. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  1229. pSurf->dwFlags &= ~DDSURF_SYSMEMALLOCATED;
  1230. }
  1231. return E_OUTOFMEMORY;
  1232. }
  1233. // Copy
  1234. pDefCreate->CreateData = *pCreateSurface;
  1235. pDefCreate->CreateData.pSList = (LPDDSURFACEINFO)MemAlloc(sizeof(DDSURFACEINFO) * pCreateSurface->dwSCnt);
  1236. if (pDefCreate->CreateData.pSList == NULL)
  1237. {
  1238. // Cleanup stuff that we allocated above
  1239. MemFree(pDefCreate);
  1240. for (i = 0; i < pCreateSurface->dwSCnt; ++i)
  1241. {
  1242. MemFree((void*)pDDSurfaceGlobal[i].fpVidMem);
  1243. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  1244. pSurf->dwFlags &= ~DDSURF_SYSMEMALLOCATED;
  1245. }
  1246. return E_OUTOFMEMORY;
  1247. }
  1248. // Copy
  1249. CopyMemory(pDefCreate->CreateData.pSList, pCreateSurface->pSList, sizeof(DDSURFACEINFO) * pCreateSurface->dwSCnt);
  1250. // Linkup
  1251. pDefCreate->pNext = ((PDDDEVICEHANDLE)pCreateSurface->hDD)->pDeferList;
  1252. ((PDDDEVICEHANDLE)pCreateSurface->hDD)->pDeferList = pDefCreate;
  1253. // We need to release the cookies allocated in InitSurfaceStructures
  1254. // because this is not an actual create. When we do the actual create, we
  1255. // will be reallocating the cookies.
  1256. for (i = 0; i < pCreateSurface->dwSCnt; ++i)
  1257. {
  1258. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  1259. DDASSERT(pSurf->dwCookie != 0);
  1260. ReleaseDX7SurfaceHandle(pSurf->pDevice, pSurf->dwCookie);
  1261. pSurf->dwCookie = 0;
  1262. }
  1263. // *************************MEMORY LEAK WARNING*********************** //
  1264. // The DEFERREDCREATE and DDSURFACEINFO allocations above will
  1265. // not be cleaned up immediately if for some reason DdCreateSurface
  1266. // (ie the caller of this function) fails after this function returns
  1267. // success. As of 3/2001, DdCreateSurface has no code path that can
  1268. // fail after we return ok below.
  1269. // ******************************************************************* //
  1270. }
  1271. return S_OK;
  1272. }
  1273. // First setup the surface desc
  1274. RtlZeroMemory(&SurfaceDesc, sizeof(SurfaceDesc));
  1275. SurfaceDesc.dwSize = sizeof(SurfaceDesc);
  1276. SurfaceDesc.ddsCaps.dwCaps = pDDSurfaceLocal[0].ddsCaps.dwCaps;
  1277. SurfaceDesc.ddsCaps.dwCaps2 = pDDSurfaceMore[0].ddsCapsEx.dwCaps2;
  1278. SurfaceDesc.ddsCaps.dwCaps3 = pDDSurfaceMore[0].ddsCapsEx.dwCaps3;
  1279. SurfaceDesc.ddsCaps.dwCaps4 = pDDSurfaceMore[0].ddsCapsEx.dwCaps4;
  1280. SurfaceDesc.ddpfPixelFormat = pDDSurfaceGlobal[0].ddpfSurface;
  1281. if ((pCreateSurface->Type == D3DRTYPE_TEXTURE) ||
  1282. (pCreateSurface->Type == D3DRTYPE_VOLUMETEXTURE))
  1283. {
  1284. SurfaceDesc.dwMipMapCount = pCreateSurface->dwSCnt;
  1285. if (SurfaceDesc.dwMipMapCount)
  1286. {
  1287. SurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT;
  1288. }
  1289. }
  1290. else if (pCreateSurface->Type == D3DRTYPE_CUBETEXTURE)
  1291. {
  1292. if (pCreateSurface->dwSCnt > 6)
  1293. {
  1294. SurfaceDesc.dwMipMapCount = pCreateSurface->dwSCnt / 6;
  1295. SurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT;
  1296. }
  1297. }
  1298. else if (pCreateSurface->dwSCnt > 1)
  1299. {
  1300. SurfaceDesc.dwBackBufferCount = pCreateSurface->dwSCnt - 1;
  1301. SurfaceDesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
  1302. }
  1303. SurfaceDesc.dwHeight = pDDSurfaceGlobal[0].wHeight;
  1304. SurfaceDesc.dwWidth = pDDSurfaceGlobal[0].wWidth;
  1305. SurfaceDesc.dwFlags |= DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  1306. if (pDDSurfaceLocal[0].dwFlags & DDRAWISURF_HASPIXELFORMAT)
  1307. {
  1308. SurfaceDesc.dwFlags |= DDSD_PIXELFORMAT;
  1309. }
  1310. if (pCreateSurface->Type == D3DRTYPE_VERTEXBUFFER)
  1311. {
  1312. SurfaceDesc.dwFVF = pCreateSurface->dwFVF;
  1313. SurfaceDesc.dwFlags |= DDSD_FVF;
  1314. }
  1315. if (SurfaceDesc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER)
  1316. {
  1317. SurfaceDesc.dwLinearSize = pCreateSurface->pSList[0].iPitch;
  1318. SurfaceDesc.dwFlags |= DDSD_LINEARSIZE;
  1319. }
  1320. if (SurfaceDesc.ddsCaps.dwCaps2 & DDSCAPS2_VOLUME)
  1321. {
  1322. SurfaceDesc.dwDepth = pCreateSurface->pSList[0].cpDepth;
  1323. SurfaceDesc.dwFlags |= DDSD_DEPTH;
  1324. }
  1325. if (SurfaceDesc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
  1326. {
  1327. // ATI Rage3 driver in Win2K still expects dwZbufferBitDepth
  1328. // in the old place in DDSD, so put it there but probably not
  1329. // set the bit in dwFlags as we don't advocate it.
  1330. ((DDSURFACEDESC*)&SurfaceDesc)->dwZBufferBitDepth =
  1331. SurfaceDesc.ddpfPixelFormat.dwZBufferBitDepth;
  1332. }
  1333. // We do not support texture stage in DX8
  1334. DDASSERT((SurfaceDesc.dwFlags & DDSD_TEXTURESTAGE) == 0);
  1335. DDASSERT(SurfaceDesc.dwTextureStage == 0);
  1336. // Now call CanCreateSurface since this is where most drivers do the
  1337. // majority of their caps checking.
  1338. RtlZeroMemory(&CanCreateData, sizeof(CanCreateData));
  1339. CanCreateData.lpDDSurfaceDesc = (DDSURFACEDESC*) &SurfaceDesc;
  1340. if (!FormatCompatibleWithDisplayFormat(((PDDDEVICEHANDLE)pCreateSurface->hDD), pCreateSurface->Format))
  1341. {
  1342. CanCreateData.bIsDifferentPixelFormat = TRUE;
  1343. }
  1344. else
  1345. {
  1346. CanCreateData.bIsDifferentPixelFormat = FALSE;
  1347. }
  1348. if (SurfaceDesc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER)
  1349. {
  1350. bRet = OsThunkDdCanCreateD3DBuffer(DDHANDLE(pCreateSurface->hDD),
  1351. &CanCreateData);
  1352. }
  1353. else
  1354. {
  1355. bRet = OsThunkDdCanCreateSurface(DDHANDLE(pCreateSurface->hDD),
  1356. &CanCreateData);
  1357. }
  1358. if ( bRet )
  1359. {
  1360. if (CanCreateData.ddRVal != S_OK)
  1361. {
  1362. if (CanCreateData.ddRVal == DDERR_SURFACELOST)
  1363. {
  1364. if (!pCreateSurface->bReUse)
  1365. {
  1366. goto DeviceLost;
  1367. }
  1368. }
  1369. return CanCreateData.ddRVal;
  1370. }
  1371. }
  1372. /*
  1373. * if the driver didn't handle it, then fail any requests to create a
  1374. * surface that differs in format from the primary surface, except for
  1375. * z buffer and alpha
  1376. */
  1377. else
  1378. {
  1379. // On Win2K, due to broken kernel, when the device is lost, the kernel
  1380. // returns DDHAL_DRIVER_NOT_HANDLED and the return code is DDERR_GENERIC.
  1381. // When we detect this, we check for device lost ourselves.
  1382. if (CanCreateData.ddRVal == DDERR_GENERIC &&
  1383. CheckForDeviceLost (pCreateSurface->hDD))
  1384. {
  1385. if (!pCreateSurface->bReUse)
  1386. {
  1387. goto DeviceLost;
  1388. }
  1389. return DDERR_SURFACELOST;
  1390. }
  1391. if (!FormatCompatibleWithDisplayFormat(((PDDDEVICEHANDLE)pCreateSurface->hDD), pCreateSurface->Format)
  1392. && !(SurfaceDesc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER|DDSCAPS_ALPHA|DDSCAPS_EXECUTEBUFFER)) )
  1393. {
  1394. return DDERR_INVALIDPIXELFORMAT;
  1395. }
  1396. }
  1397. // Calculate the surface pitch. The driver may override this, but if we
  1398. // don't initialize it and the driver doesn't explicitly specify it, then
  1399. // the kernel may fail the allocation.
  1400. if (!(SurfaceDesc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER))
  1401. {
  1402. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  1403. {
  1404. if (SurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
  1405. {
  1406. pDDSurfaceGlobal[i].lPitch = ((PDDDEVICEHANDLE)pCreateSurface->hDD)->DisplayPitch;
  1407. }
  1408. else if ((pDDSurfaceLocal[0].dwFlags & DDRAWISURF_HASPIXELFORMAT) &&
  1409. (pDDSurfaceGlobal[0].ddpfSurface.dwRGBBitCount > 0))
  1410. {
  1411. pDDSurfaceGlobal[i].lPitch =
  1412. (pDDSurfaceGlobal[0].ddpfSurface.dwRGBBitCount / 8) *
  1413. pDDSurfaceGlobal[i].wWidth;
  1414. // Assume that they need to be 8 byte aligned.
  1415. pDDSurfaceGlobal[i].lPitch += 7;
  1416. pDDSurfaceGlobal[i].lPitch &= 0xfffffff8;
  1417. }
  1418. }
  1419. }
  1420. // If the surface requires attachments, we need to set that up before the
  1421. // CreateSurface call.
  1422. if (pCreateSurface->dwSCnt > 1)
  1423. {
  1424. // First, create all of the surface objects
  1425. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  1426. {
  1427. phInSurface[i] = OsThunkDdCreateSurfaceObject(DDHANDLE(pCreateSurface->hDD),
  1428. NULL,
  1429. &pDDSurfaceLocal[i],
  1430. &pDDSurfaceMore[i],
  1431. &pDDSurfaceGlobal[i],
  1432. FALSE);
  1433. if (phInSurface[i] == NULL)
  1434. {
  1435. for (j = 0; j < i; j++)
  1436. {
  1437. OsThunkDdDeleteSurfaceObject(phInSurface[j]);
  1438. }
  1439. // Looks like we are lost or something. Check it out.
  1440. if (CheckForDeviceLost (pCreateSurface->hDD))
  1441. {
  1442. if (!pCreateSurface->bReUse)
  1443. {
  1444. goto DeviceLost;
  1445. }
  1446. return DDERR_SURFACELOST;
  1447. }
  1448. return E_FAIL;
  1449. }
  1450. }
  1451. // Now attach them all
  1452. for (i = 1; i < pCreateSurface->dwSCnt; i++)
  1453. {
  1454. bRet = OsThunkDdAttachSurface(phInSurface[SelectAttachmentSurface(pCreateSurface,i)],
  1455. phInSurface[i]);
  1456. // smac: handle error condition
  1457. }
  1458. // If it's the primary surface chain, I also need to attach the back
  1459. // to the front (to avoid potential compatibility issues).
  1460. if (pDDSurfaceLocal[0].ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
  1461. {
  1462. bRet = OsThunkDdAttachSurface(phInSurface[pCreateSurface->dwSCnt - 1],
  1463. phInSurface[0]);
  1464. }
  1465. }
  1466. // Preset an error in case the kernel can't write status
  1467. // back for some reason.
  1468. CreateData7.ddRVal = E_FAIL;
  1469. CreateData7.dwSCnt = pCreateSurface->dwSCnt;
  1470. if (SurfaceDesc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER)
  1471. {
  1472. bRet = OsThunkDdCreateD3DBuffer(DDHANDLE(pCreateSurface->hDD),
  1473. phInSurface,
  1474. (LPDDSURFACEDESC)&SurfaceDesc,
  1475. pDDSurfaceGlobal,
  1476. pDDSurfaceLocal,
  1477. pDDSurfaceMore,
  1478. (PDD_CREATESURFACEDATA) &CreateData7,
  1479. phOutSurface);
  1480. }
  1481. else
  1482. {
  1483. bRet = OsThunkDdCreateSurface(DDHANDLE(pCreateSurface->hDD),
  1484. phInSurface,
  1485. (LPDDSURFACEDESC)&SurfaceDesc,
  1486. pDDSurfaceGlobal,
  1487. pDDSurfaceLocal,
  1488. pDDSurfaceMore,
  1489. (PDD_CREATESURFACEDATA) &CreateData7,
  1490. phOutSurface);
  1491. }
  1492. if ( bRet && (CreateData7.ddRVal != S_OK))
  1493. {
  1494. if (pCreateSurface->dwSCnt > 1)
  1495. {
  1496. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  1497. {
  1498. OsThunkDdDeleteSurfaceObject(phInSurface[i]);
  1499. }
  1500. }
  1501. if (CreateData7.ddRVal == DDERR_SURFACELOST)
  1502. {
  1503. if (!pCreateSurface->bReUse)
  1504. {
  1505. goto DeviceLost;
  1506. }
  1507. }
  1508. // Broken Win2K kernel fails with DDERR_OUTOFVIDEOMEMORY, so handle this case
  1509. else if ((CreateData7.ddRVal == DDERR_OUTOFVIDEOMEMORY ||
  1510. CreateData7.ddRVal == DDERR_GENERIC) &&
  1511. CheckForDeviceLost (pCreateSurface->hDD))
  1512. {
  1513. if (!pCreateSurface->bReUse)
  1514. {
  1515. goto DeviceLost;
  1516. }
  1517. CreateData7.ddRVal = DDERR_SURFACELOST;
  1518. }
  1519. return CreateData7.ddRVal;
  1520. }
  1521. if (pDDSurfaceLocal[0].ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
  1522. {
  1523. pCreateSurface->Pool = D3DPOOL_NONLOCALVIDMEM;
  1524. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  1525. {
  1526. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  1527. pSurf->Pool = D3DPOOL_NONLOCALVIDMEM;
  1528. }
  1529. }
  1530. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  1531. {
  1532. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  1533. pSurf->hSurface = phOutSurface[i];
  1534. }
  1535. return CreateData7.ddRVal;
  1536. }
  1537. /*****************************Private*Routine******************************\
  1538. * CreateSysMemSurface
  1539. *
  1540. * History:
  1541. * 06-Dec-1999 -by- Scott MacDonald [smac]
  1542. * Wrote it.
  1543. \**************************************************************************/
  1544. #undef DPF_MODNAME
  1545. #define DPF_MODNAME "CreateSysMemSurface"
  1546. HRESULT
  1547. CreateSysMemSurface(
  1548. PD3D8_CREATESURFACEDATA pCreateSurface,
  1549. DD_SURFACE_LOCAL* pDDSurfaceLocal,
  1550. DD_SURFACE_GLOBAL* pDDSurfaceGlobal,
  1551. DD_SURFACE_MORE* pDDSurfaceMore,
  1552. BOOL bIsLost
  1553. )
  1554. {
  1555. DWORD i;
  1556. DWORD j;
  1557. HRESULT hr;
  1558. BOOL bRet;
  1559. DDSURFHANDLE* pSurf;
  1560. hr = S_OK;
  1561. for (i = 0; i < pCreateSurface->dwSCnt; i++)
  1562. {
  1563. pDDSurfaceGlobal[i].fpVidMem = (ULONG_PTR)pCreateSurface->pSList[i].pbPixels;
  1564. pDDSurfaceGlobal[i].lPitch = pCreateSurface->pSList[i].iPitch;
  1565. if ((pCreateSurface->Type == D3DRTYPE_VOLUME) ||
  1566. (pCreateSurface->Type == D3DRTYPE_VOLUMETEXTURE))
  1567. {
  1568. pDDSurfaceGlobal[i].dwBlockSizeY = pCreateSurface->pSList[i].iSlicePitch;
  1569. }
  1570. // Hack for NT; they don't support FourCC codes
  1571. if (pDDSurfaceGlobal[i].ddpfSurface.dwFlags == DDPF_FOURCC)
  1572. {
  1573. if (pCreateSurface->Format == D3DFMT_UYVY ||
  1574. pCreateSurface->Format == D3DFMT_YUY2)
  1575. {
  1576. pDDSurfaceGlobal[i].ddpfSurface.dwRGBBitCount = 16;
  1577. // lie about pitch
  1578. pDDSurfaceGlobal[i].lPitch =
  1579. ((pDDSurfaceGlobal[i].wWidth*2 + 7) & ~7);
  1580. }
  1581. else if (pCreateSurface->Format == D3DFMT_DXT1 ||
  1582. pCreateSurface->Format == D3DFMT_DXT2 ||
  1583. pCreateSurface->Format == D3DFMT_DXT3 ||
  1584. pCreateSurface->Format == D3DFMT_DXT4 ||
  1585. pCreateSurface->Format == D3DFMT_DXT5)
  1586. {
  1587. DWORD blksize;
  1588. DWORD realwidth = pDDSurfaceGlobal[i].wWidth;
  1589. DWORD realheight = pDDSurfaceGlobal[i].wHeight;
  1590. WORD dx, dy;
  1591. if (pCreateSurface->Format == D3DFMT_DXT1)
  1592. {
  1593. blksize = 8;
  1594. }
  1595. else
  1596. {
  1597. blksize = 16;
  1598. }
  1599. // HACK STOLEN FROM DX7 DDHEL
  1600. // <kd> used the same logic as dx7 to avoid compat pain
  1601. // The NT bug won't let us create this surface unless we lie.
  1602. // We have to make up a width, height, pitch, and pixel size
  1603. // that GDI will accept as valid.
  1604. dx = (WORD)((realwidth + 3) >> 2); // number of 4x4 blocks in a row
  1605. dy = (WORD)((realheight + 3) >> 2); // number of 4x4 blocks in a column
  1606. pDDSurfaceGlobal[i].wHeight = dy; // lie about height
  1607. pDDSurfaceGlobal[i].lPitch = dx*blksize; // lie about pitch
  1608. pDDSurfaceGlobal[i].wWidth = (WORD)pDDSurfaceGlobal[i].lPitch; // lie about width
  1609. pDDSurfaceGlobal[i].ddpfSurface.dwRGBBitCount = 8; // lie about pixel size
  1610. }
  1611. }
  1612. // The presence of a software driver can make a sysmem surface act
  1613. // like a vidmem surface, so we need to explicitly say that it's in sysmem
  1614. pDDSurfaceLocal[i].ddsCaps.dwCaps &=
  1615. ~(DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_NONLOCALVIDMEM);
  1616. pDDSurfaceLocal[i].ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
  1617. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  1618. pSurf->hSurface = OsThunkDdCreateSurfaceObject(DDHANDLE(pCreateSurface->hDD),
  1619. NULL,
  1620. &pDDSurfaceLocal[i],
  1621. &pDDSurfaceMore[i],
  1622. &pDDSurfaceGlobal[i],
  1623. TRUE);
  1624. if (pSurf->hSurface == NULL)
  1625. {
  1626. // Note that the main reason for this error is actually
  1627. // out-of-memory; but it could also point at a bug
  1628. // somewhere between the validation logic in kernel
  1629. // and the validation logic in our runtime,
  1630. DPF_ERR("Kernel failed registration of sys-mem object; out of system-memory condition");
  1631. hr = E_OUTOFMEMORY;
  1632. }
  1633. }
  1634. // If we successfully created the handles, then we create any attachments
  1635. // that we might require.
  1636. if (SUCCEEDED(hr))
  1637. {
  1638. for (i = 1; i < pCreateSurface->dwSCnt; i++)
  1639. {
  1640. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  1641. bRet = OsThunkDdAttachSurface(
  1642. ((PDDSURFHANDLE)pCreateSurface->pSList[
  1643. SelectAttachmentSurface(pCreateSurface,i)
  1644. ].hKernelHandle)->hSurface,
  1645. pSurf->hSurface);
  1646. // smac: handle error condition
  1647. }
  1648. }
  1649. // If we're still OK, then we should call CreateSurfaceEx
  1650. if (SUCCEEDED(hr))
  1651. {
  1652. if (pDDSurfaceMore[0].dwSurfaceHandle != 0)
  1653. {
  1654. // If using a software driver, we need to call CreateSurfaceEx
  1655. // in the software driver; otherwsie, we call the kernel
  1656. if (!IS_SOFTWARE_DRIVER(pCreateSurface->hDD))
  1657. {
  1658. if (bIsLost)
  1659. {
  1660. // We set defer on the top level so CreateSurfaceEx gets called on Reset
  1661. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[0].hKernelHandle;
  1662. pSurf->dwFlags |= DDSURF_DEFERCREATEEX;
  1663. return hr;
  1664. }
  1665. hr = OsThunkDdCreateSurfaceEx(
  1666. DDHANDLE(pCreateSurface->hDD),
  1667. ((PDDSURFHANDLE)pCreateSurface->pSList[0].hKernelHandle)->hSurface,
  1668. pDDSurfaceMore[0].dwSurfaceHandle);
  1669. if (FAILED(hr))
  1670. {
  1671. if (hr == DDERR_SURFACELOST ||
  1672. CheckForDeviceLost (pCreateSurface->hDD)) // Due to broken Win2K implementation
  1673. {
  1674. // We set defer on the top level so CreateSurfaceEx gets called on Reset
  1675. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[0].hKernelHandle;
  1676. pSurf->dwFlags |= DDSURF_DEFERCREATEEX;
  1677. return S_OK;
  1678. }
  1679. }
  1680. }
  1681. }
  1682. }
  1683. return hr;
  1684. }
  1685. BOOL IsWhistler()
  1686. {
  1687. OSVERSIONINFOEX osvi;
  1688. DWORDLONG dwlConditionMask = 0;
  1689. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  1690. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  1691. osvi.dwMajorVersion = 5;
  1692. osvi.dwMinorVersion = 1;
  1693. VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION,
  1694. VER_GREATER_EQUAL );
  1695. VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION,
  1696. VER_GREATER_EQUAL );
  1697. return VerifyVersionInfo(&osvi,
  1698. VER_MAJORVERSION|VER_MINORVERSION,
  1699. dwlConditionMask);
  1700. }
  1701. // ResetUniqueness will cause runtime to think there is a device lost,
  1702. // have to do that only for whistler when fscreen app alt-tab away to
  1703. // desktop mode that is the same as the fullscreen, whistler
  1704. void ResetUniqueness( HANDLE hDD )
  1705. {
  1706. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  1707. if (pDeviceHandle->bIsWhistler)
  1708. pDeviceHandle->DisplayUniqueness = 0;
  1709. }
  1710. /*****************************Private*Routine******************************\
  1711. * DdCreateSurface
  1712. *
  1713. * History:
  1714. * 2-Nov-1999 -by- Scott MacDonald [smac]
  1715. * Wrote it.
  1716. \**************************************************************************/
  1717. #undef DPF_MODNAME
  1718. #define DPF_MODNAME "DdCreateSurface"
  1719. HRESULT
  1720. APIENTRY
  1721. DdCreateSurface(
  1722. PD3D8_CREATESURFACEDATA pCreateSurface
  1723. )
  1724. {
  1725. ULONG i;
  1726. ULONG j;
  1727. DDSURFACEDESC2 SurfaceDesc;
  1728. HANDLE hInSurface;
  1729. HANDLE hOutSurface;
  1730. DD_SURFACE_LOCAL SurfaceLocal;
  1731. DD_SURFACE_GLOBAL SurfaceGlobal;
  1732. DD_SURFACE_MORE SurfaceMore;
  1733. DD_SURFACE_LOCAL* pDDSurfaceLocal = NULL;
  1734. DD_SURFACE_GLOBAL* pDDSurfaceGlobal = NULL;
  1735. DD_SURFACE_MORE* pDDSurfaceMore = NULL;
  1736. HANDLE* phInSurface = NULL;
  1737. HANDLE* phOutSurface = NULL;
  1738. HRESULT hr;
  1739. BOOL bSysMemCreate = FALSE;
  1740. PDDSURFHANDLE pSurf;
  1741. BOOL bIsLost = FALSE;
  1742. DWORD dwNumToCreate;
  1743. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pCreateSurface->hDD;
  1744. dwNumToCreate = pCreateSurface->dwSCnt;
  1745. // If the device is lost, we don't want to actually allocate vidmem, but
  1746. // we still need to support sysmem surfaces. We also have to fake up
  1747. // vidmem allocations since we only want to expose lost devices in a
  1748. // couple of places.
  1749. if (CheckForDeviceLost (pCreateSurface->hDD))
  1750. {
  1751. bIsLost = TRUE;
  1752. if (pCreateSurface->bReUse)
  1753. {
  1754. return DDERR_SURFACELOST;
  1755. }
  1756. }
  1757. // For every surface, convert to the kernel's surface data structure,
  1758. // call the kernel, then convert back:
  1759. hr = S_OK;
  1760. // If we are only creating one, no need to allocate gobs of memory; otherwise, do it
  1761. if (dwNumToCreate == 1)
  1762. {
  1763. RtlZeroMemory(&SurfaceLocal, sizeof(SurfaceLocal));
  1764. RtlZeroMemory(&SurfaceGlobal, sizeof(SurfaceGlobal));
  1765. RtlZeroMemory(&SurfaceMore, sizeof(SurfaceMore));
  1766. hInSurface = NULL;
  1767. hOutSurface = NULL;
  1768. pDDSurfaceLocal = &SurfaceLocal;
  1769. pDDSurfaceGlobal = &SurfaceGlobal;
  1770. pDDSurfaceMore = &SurfaceMore;
  1771. phInSurface = &hInSurface;
  1772. phOutSurface = &hOutSurface;
  1773. }
  1774. else
  1775. {
  1776. pDDSurfaceLocal = (DD_SURFACE_LOCAL*) MemAlloc(
  1777. sizeof(DD_SURFACE_LOCAL) * dwNumToCreate);
  1778. pDDSurfaceGlobal = (DD_SURFACE_GLOBAL*) MemAlloc(
  1779. sizeof(DD_SURFACE_GLOBAL) * dwNumToCreate);
  1780. pDDSurfaceMore = (DD_SURFACE_MORE*) MemAlloc(
  1781. sizeof(DD_SURFACE_MORE) * dwNumToCreate);
  1782. phInSurface = (HANDLE*) MemAlloc(sizeof(HANDLE) * dwNumToCreate);
  1783. phOutSurface = (HANDLE*) MemAlloc(
  1784. sizeof(HANDLE) * dwNumToCreate);
  1785. if ((pDDSurfaceLocal == NULL) ||
  1786. (pDDSurfaceGlobal == NULL) ||
  1787. (pDDSurfaceMore == NULL) ||
  1788. (phInSurface == NULL) ||
  1789. (phOutSurface == NULL))
  1790. {
  1791. hr = E_OUTOFMEMORY;
  1792. goto CleanupCreate;
  1793. }
  1794. }
  1795. InitSurfaceStructures (pCreateSurface,
  1796. pDDSurfaceLocal,
  1797. pDDSurfaceGlobal,
  1798. pDDSurfaceMore);
  1799. // Allocate the internal surface structures for each surface in the chain
  1800. // and initialize it if we are not reusing the surface
  1801. if (!pCreateSurface->bReUse)
  1802. {
  1803. for (i = 0; i < dwNumToCreate; i++)
  1804. {
  1805. pSurf = (PDDSURFHANDLE) MemAlloc(sizeof(DDSURFHANDLE));
  1806. if (pSurf == NULL)
  1807. {
  1808. hr = E_OUTOFMEMORY;
  1809. goto CleanupCreate;
  1810. }
  1811. pSurf->Pool = pCreateSurface->Pool;
  1812. pSurf->Format = pCreateSurface->Format;
  1813. pSurf->Type = pCreateSurface->Type;
  1814. // This is sort of a hack to save space. For regular surfaces, we need
  1815. // to know the height to handle the lost case, but for volume textures,
  1816. // we really need to know the depth. To save space, we will re-use the
  1817. // same variable.
  1818. if ((pSurf->Type == D3DRTYPE_VOLUME) ||
  1819. (pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
  1820. {
  1821. pSurf->dwHeight = pCreateSurface->pSList[i].cpDepth;
  1822. }
  1823. else
  1824. {
  1825. pSurf->dwHeight = pCreateSurface->pSList[i].cpHeight;
  1826. }
  1827. pCreateSurface->pSList[i].hKernelHandle = (HANDLE) pSurf;
  1828. pSurf->pDevice = (PDDDEVICEHANDLE) pCreateSurface->hDD;
  1829. // You may find it wasteful that we assign handles to each mipmap level,
  1830. // even though we only call CreateSurfaceEx on the topmost level. We need
  1831. // to do this, however, since DX7 worked this way and it also call
  1832. // CreateSurfaceEx fpVidMem = 0 at release time on each level of the mipmap.
  1833. pSurf->dwCookie = pDDSurfaceMore[i].dwSurfaceHandle;
  1834. // Now figure out if this is a sysmem surface, a software driver
  1835. // surface, or a HAL surface.
  1836. if (pSurf->Pool != D3DPOOL_SYSTEMMEM)
  1837. {
  1838. // If they are running w/ a software driver (refrast, RGB HEL, etc.),
  1839. // we will not allow any surfaces to be created in video memory except
  1840. // for the primary flipping chain. And also for surfaces marked
  1841. // USAGE_OFFSCREENPLAIN (which are used for the cursors)
  1842. if (IS_SOFTWARE_DRIVER(pCreateSurface->hDD) &&
  1843. !(pCreateSurface->dwUsage & D3DUSAGE_PRIMARYSURFACE) &&
  1844. !(pCreateSurface->dwUsage & D3DUSAGE_OFFSCREENPLAIN))
  1845. {
  1846. pSurf->dwFlags |= DDSURF_SOFTWARE;
  1847. }
  1848. else
  1849. {
  1850. pSurf->dwFlags |= DDSURF_HAL;
  1851. }
  1852. }
  1853. if (pCreateSurface->bTreatAsVidMem == TRUE)
  1854. {
  1855. // For objects that should be treated as non-persistent
  1856. // i.e. Reset fails unless these are all freed; we
  1857. // set a flag here and check it in DoVidMemSurfacesExist()
  1858. pSurf->dwFlags |= DDSURF_TREATASVIDMEM;
  1859. }
  1860. // If a software driver will see this surface (either because it
  1861. // will create it, or because it's a sysmem surface that will need
  1862. // to handle CreateEx), we need to build a heavyweight surface structure.
  1863. if (IS_SOFTWARE_DRIVER(pCreateSurface->hDD))
  1864. {
  1865. if (!(pSurf->dwFlags & DDSURF_HAL) &&
  1866. (pSurf->dwCookie != 0))
  1867. {
  1868. pSurf->pLcl = SwDDIBuildHeavyWeightSurface(
  1869. pSurf->pDevice->pDD,
  1870. pCreateSurface,
  1871. &pDDSurfaceLocal[i],
  1872. &pDDSurfaceGlobal[i],
  1873. &pDDSurfaceMore[i],
  1874. i);
  1875. if (pSurf->pLcl == NULL)
  1876. {
  1877. hr = E_OUTOFMEMORY;
  1878. goto CleanupCreate;
  1879. }
  1880. }
  1881. }
  1882. }
  1883. }
  1884. else // fill in the new cookie
  1885. {
  1886. for (i = 0; i < dwNumToCreate; i++)
  1887. {
  1888. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  1889. DDASSERT(pSurf->dwCookie == 0);
  1890. pSurf->dwCookie = pDDSurfaceMore[i].dwSurfaceHandle;
  1891. }
  1892. }
  1893. // Now create the actual surfaces
  1894. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[0].hKernelHandle;
  1895. if (pSurf->Pool == D3DPOOL_SYSTEMMEM)
  1896. {
  1897. hr = CreateSysMemSurface(
  1898. pCreateSurface,
  1899. pDDSurfaceLocal,
  1900. pDDSurfaceGlobal,
  1901. pDDSurfaceMore,
  1902. bIsLost);
  1903. }
  1904. else if (pSurf->dwFlags & DDSURF_SOFTWARE)
  1905. {
  1906. // Call the software rasterizer if it can handle it.
  1907. // This allows them to allocate the memory, etc., but
  1908. // we still need to call the kernel to create an object
  1909. hr = SwDDICreateSurface(pCreateSurface,
  1910. pDDSurfaceLocal,
  1911. pDDSurfaceGlobal,
  1912. pDDSurfaceMore);
  1913. // We only need to get a kernel-handle
  1914. // for back-buffers
  1915. if (SUCCEEDED(hr) && (pCreateSurface->dwUsage & D3DUSAGE_BACKBUFFER))
  1916. {
  1917. hr = CreateSysMemSurface(pCreateSurface,
  1918. pDDSurfaceLocal,
  1919. pDDSurfaceGlobal,
  1920. pDDSurfaceMore,
  1921. bIsLost);
  1922. if (FAILED(hr))
  1923. {
  1924. // we need to mark all the surfaces
  1925. // as completely built so that
  1926. // we free them correctly
  1927. for (i = 0; i < dwNumToCreate; i++)
  1928. {
  1929. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  1930. pSurf->dwFlags |= DDSURF_CREATECOMPLETE;
  1931. }
  1932. }
  1933. }
  1934. }
  1935. else
  1936. {
  1937. hr = CreateVidMemSurface (pCreateSurface,
  1938. pDDSurfaceLocal,
  1939. pDDSurfaceGlobal,
  1940. pDDSurfaceMore,
  1941. phInSurface,
  1942. phOutSurface,
  1943. bIsLost);
  1944. }
  1945. if (FAILED(hr))
  1946. {
  1947. goto CleanupCreate;
  1948. }
  1949. // Everything worked so far, so now we just need to finish up.
  1950. for(i = 0; i < dwNumToCreate; i++)
  1951. {
  1952. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  1953. pSurf->dwFlags |= DDSURF_CREATECOMPLETE;
  1954. if (!(pSurf->dwFlags & DDSURF_HAL))
  1955. {
  1956. // It's a sysmem surface - either explicit or a software driver
  1957. pSurf->fpVidMem = (ULONG_PTR)pCreateSurface->pSList[i].pbPixels;
  1958. pSurf->dwLinearSize = pCreateSurface->pSList[i].iPitch;
  1959. pSurf->lPitch = pCreateSurface->pSList[i].iPitch;
  1960. pSurf->lSlicePitch = pCreateSurface->pSList[i].iSlicePitch;
  1961. }
  1962. else
  1963. {
  1964. pSurf->fpVidMem = (ULONG_PTR)pDDSurfaceGlobal[i].fpVidMem;
  1965. pSurf->dwLinearSize = pDDSurfaceGlobal[i].dwLinearSize;
  1966. pCreateSurface->pSList[i].iPitch = pSurf->dwLinearSize;
  1967. pSurf->lPitch = pDDSurfaceGlobal[i].lPitch;
  1968. if ((pSurf->Type == D3DRTYPE_VOLUME) ||
  1969. (pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
  1970. {
  1971. pSurf->lSlicePitch = pDDSurfaceGlobal[i].dwBlockSizeY;
  1972. }
  1973. else
  1974. {
  1975. pSurf->lSlicePitch = 0;
  1976. }
  1977. }
  1978. // If it's a software driver, we may need to attach surfaces
  1979. if ((0==(pSurf->dwFlags & DDSURF_HAL)) &&
  1980. (IS_SOFTWARE_DRIVER(pCreateSurface->hDD)) &&
  1981. (i > 0))
  1982. {
  1983. // Cubes are created strangely... Each face is attached to the root,
  1984. // and each mipsublevel is attached to its face
  1985. DDASSERT(pCreateSurface->Type != D3DRTYPE_CUBETEXTURE || pCreateSurface->dwSCnt>=6);
  1986. SwDDIAttachSurfaces (
  1987. ((PDDSURFHANDLE)pCreateSurface->pSList[
  1988. SelectAttachmentSurface(pCreateSurface,i)
  1989. ].hKernelHandle)->pLcl,
  1990. pSurf->pLcl);
  1991. }
  1992. }
  1993. // If it's a software driver, we need to call CreateSurfaceEx after
  1994. // all of the attachments are made.
  1995. if ((IS_SOFTWARE_DRIVER(pCreateSurface->hDD)) &&
  1996. (pSurf->dwCookie != 0))
  1997. {
  1998. SwDDICreateSurfaceEx (pDevice->pDD,
  1999. ((PDDSURFHANDLE)pCreateSurface->pSList[0].hKernelHandle)->pLcl);
  2000. }
  2001. // Now save the surfaces in a linked list
  2002. // If re-using, then we are already on the list so don't do anything
  2003. if (!pCreateSurface->bReUse)
  2004. {
  2005. for (i = 0; i < dwNumToCreate; i++)
  2006. {
  2007. ((PDDSURFHANDLE)(pCreateSurface->pSList[i].hKernelHandle))->pNext =
  2008. pDevice->pSurfList;
  2009. ((PDDSURFHANDLE)(pCreateSurface->pSList[i].hKernelHandle))->pPrevious =
  2010. NULL;
  2011. if (pDevice->pSurfList != NULL)
  2012. {
  2013. pDevice->pSurfList->pPrevious = (PDDSURFHANDLE)(pCreateSurface->pSList[i].hKernelHandle);
  2014. }
  2015. pDevice->pSurfList = (PDDSURFHANDLE)(pCreateSurface->pSList[i].hKernelHandle);
  2016. }
  2017. }
  2018. CleanupCreate:
  2019. if (1 != dwNumToCreate)
  2020. {
  2021. if (pDDSurfaceLocal != NULL)
  2022. {
  2023. MemFree(pDDSurfaceLocal);
  2024. }
  2025. if (pDDSurfaceGlobal != NULL)
  2026. {
  2027. MemFree(pDDSurfaceGlobal);
  2028. }
  2029. if (pDDSurfaceMore != NULL)
  2030. {
  2031. MemFree(pDDSurfaceMore);
  2032. }
  2033. if (phInSurface != NULL)
  2034. {
  2035. MemFree(phInSurface);
  2036. }
  2037. if (phOutSurface != NULL)
  2038. {
  2039. MemFree(phOutSurface);
  2040. }
  2041. }
  2042. if (FAILED(hr))
  2043. {
  2044. // Clean everything up
  2045. for (i = 0; i < dwNumToCreate; i++)
  2046. {
  2047. pSurf = (PDDSURFHANDLE) pCreateSurface->pSList[i].hKernelHandle;
  2048. if (pSurf != NULL)
  2049. {
  2050. FreeSurfaceObject(pSurf);
  2051. // If we are reusing, then we need to keep the pSurf around
  2052. // for a retry
  2053. if (!pCreateSurface->bReUse)
  2054. {
  2055. MemFree(pSurf);
  2056. }
  2057. }
  2058. pCreateSurface->pSList[i].hKernelHandle = NULL;
  2059. }
  2060. }
  2061. return(MapLegacyResult(hr));
  2062. }
  2063. /******************************Public*Routine******************************\
  2064. *
  2065. * D3dContextCreate
  2066. *
  2067. * History:
  2068. * Mon Jun 03 14:18:29 1996 -by- Drew Bliss [drewb]
  2069. * Created
  2070. *
  2071. \**************************************************************************/
  2072. #undef DPF_MODNAME
  2073. #define DPF_MODNAME "D3dContextCreate"
  2074. DWORD WINAPI
  2075. D3dContextCreate(PD3D8_CONTEXTCREATEDATA pCreateContext)
  2076. {
  2077. PD3DCONTEXTHANDLE pContext = NULL;
  2078. BOOL bIsLost = FALSE;
  2079. DWORD dwRet = DDHAL_DRIVER_HANDLED;
  2080. // Don't call the driver if the device is lost
  2081. pCreateContext->ddrval = S_OK;
  2082. if (!CheckForDeviceLost (pCreateContext->hDD))
  2083. {
  2084. dwRet = OsThunkD3dContextCreate(DDHANDLE(pCreateContext->hDD),
  2085. GetSurfHandle(pCreateContext->hSurface),
  2086. GetSurfHandle(pCreateContext->hDDSZ),
  2087. (D3DNTHAL_CONTEXTCREATEI *)pCreateContext);
  2088. if (pCreateContext->ddrval == DDERR_SURFACELOST)
  2089. {
  2090. bIsLost = TRUE;
  2091. pCreateContext->ddrval = S_OK;
  2092. CheckForDeviceLost (pCreateContext->hDD);
  2093. }
  2094. }
  2095. else
  2096. {
  2097. bIsLost = TRUE;
  2098. }
  2099. // We need to abstract the handle for a couple of reasons:
  2100. // 1. The context handle can change due to lost devices, and
  2101. // we'd prefer to abstract this from D3D.
  2102. // 2. We need to know the device that this handle belongs to
  2103. // so we can always check for device lost.
  2104. if (pCreateContext->ddrval == S_OK)
  2105. {
  2106. pContext = (PD3DCONTEXTHANDLE) MemAlloc(sizeof(D3DCONTEXTHANDLE));
  2107. if (pContext == NULL)
  2108. {
  2109. // smac: clean up
  2110. pCreateContext->dwhContext = (ULONG_PTR) NULL;
  2111. pCreateContext->ddrval = E_OUTOFMEMORY;
  2112. }
  2113. else
  2114. {
  2115. pContext->pDevice = pCreateContext->hDD;
  2116. if (bIsLost)
  2117. {
  2118. pContext->dwFlags = D3DCONTEXT_DEFERCREATE;
  2119. pContext->dwPID = pCreateContext->dwPID;
  2120. pContext->hDeferHandle = (HANDLE)pCreateContext->dwhContext;
  2121. pContext->pSurface = pCreateContext->hSurface;
  2122. pContext->pDDSZ = pCreateContext->hDDSZ;
  2123. }
  2124. else
  2125. {
  2126. pContext->dwhContext = (HANDLE) pCreateContext->dwhContext;
  2127. }
  2128. pCreateContext->dwhContext = (ULONG_PTR) pContext;
  2129. }
  2130. }
  2131. pCreateContext->ddrval = MapLegacyResult(pCreateContext->ddrval);
  2132. return dwRet;
  2133. }
  2134. /******************************Public*Routine******************************\
  2135. *
  2136. * D3dContextDestroy
  2137. *
  2138. * History:
  2139. * Mon Jun 03 14:18:29 1996 -by- Drew Bliss [drewb]
  2140. * Created
  2141. *
  2142. \**************************************************************************/
  2143. #undef DPF_MODNAME
  2144. #define DPF_MODNAME "D3dContextDestroy"
  2145. DWORD WINAPI
  2146. D3dContextDestroy(PD3D8_CONTEXTDESTROYDATA pDestroyContext)
  2147. {
  2148. PD3DCONTEXTHANDLE pContext = (PD3DCONTEXTHANDLE) pDestroyContext->dwhContext;
  2149. CheckForDeviceLost (pContext->pDevice);
  2150. pDestroyContext->ddrval = S_OK;
  2151. if (pContext->dwhContext)
  2152. {
  2153. pDestroyContext->dwhContext = (LONG_PTR) pContext->dwhContext;
  2154. OsThunkD3dContextDestroy((LPD3DNTHAL_CONTEXTDESTROYDATA) pDestroyContext);
  2155. }
  2156. pContext->pDevice->pContext = NULL;
  2157. MemFree(pContext);
  2158. pDestroyContext->ddrval = MapLegacyResult(pDestroyContext->ddrval);
  2159. return DDHAL_DRIVER_HANDLED;
  2160. }
  2161. /******************************Public*Routine******************************\
  2162. *
  2163. * D3dContextDestroyAll
  2164. *
  2165. * History:
  2166. * Mon Jun 03 14:18:29 1996 -by- Drew Bliss [drewb]
  2167. * Created
  2168. *
  2169. \**************************************************************************/
  2170. #undef DPF_MODNAME
  2171. #define DPF_MODNAME "D3dContextDestroyAll"
  2172. DWORD WINAPI
  2173. D3dContextDestroyAll(PD3D8_CONTEXTDESTROYALLDATA pDestroyAllContext)
  2174. {
  2175. OsThunkD3dContextDestroyAll((LPD3DNTHAL_CONTEXTDESTROYALLDATA) pDestroyAllContext);
  2176. // smac: Need to add code here to free all contexts for each device
  2177. // the PID has?
  2178. return DDHAL_DRIVER_HANDLED;
  2179. }
  2180. /******************************Public*Routine******************************\
  2181. *
  2182. * DdGetDriverState
  2183. *
  2184. * History:
  2185. * Mon Jun 03 14:18:29 1996 -by- Drew Bliss [drewb]
  2186. * Created
  2187. *
  2188. \**************************************************************************/
  2189. #undef DPF_MODNAME
  2190. #define DPF_MODNAME "DdGetDriverState"
  2191. DWORD WINAPI DdGetDriverState(PD3D8_GETDRIVERSTATEDATA pGetDriverState)
  2192. {
  2193. PD3DCONTEXTHANDLE pContext = (PD3DCONTEXTHANDLE) pGetDriverState->dwhContext;
  2194. DWORD dwRet = DDHAL_DRIVER_HANDLED;
  2195. ULONG_PTR pTemp;
  2196. pGetDriverState->ddRVal = E_FAIL;
  2197. if (!CheckForDeviceLost (pContext->pDevice))
  2198. {
  2199. pTemp = pGetDriverState->dwhContext;
  2200. pGetDriverState->dwhContext = (ULONG_PTR) pContext->dwhContext;
  2201. dwRet = OsThunkDdGetDriverState ((DD_GETDRIVERSTATEDATA*)pGetDriverState);
  2202. pGetDriverState->dwhContext = pTemp;
  2203. if (pGetDriverState->ddRVal == DDERR_SURFACELOST)
  2204. {
  2205. pGetDriverState->ddRVal = E_FAIL;
  2206. }
  2207. }
  2208. pGetDriverState->ddRVal = MapLegacyResult(pGetDriverState->ddRVal);
  2209. return dwRet;
  2210. }
  2211. /******************************Public*Routine******************************\
  2212. *
  2213. * D3dValidateTextureStageState
  2214. *
  2215. * History:
  2216. * Mon Jun 03 14:18:29 1996 -by- Drew Bliss [drewb]
  2217. * Created
  2218. *
  2219. \**************************************************************************/
  2220. #undef DPF_MODNAME
  2221. #define DPF_MODNAME "D3dValidateTextureStageState"
  2222. DWORD WINAPI D3dValidateTextureStageState(PD3D8_VALIDATETEXTURESTAGESTATEDATA pValidate)
  2223. {
  2224. PD3DCONTEXTHANDLE pContext = (PD3DCONTEXTHANDLE) pValidate->dwhContext;
  2225. DWORD dwRet = DDHAL_DRIVER_HANDLED;
  2226. ULONG_PTR pTemp;
  2227. pValidate->ddrval = D3DERR_DEVICELOST;
  2228. pValidate->dwNumPasses = 0;
  2229. if (!CheckForDeviceLost (pContext->pDevice))
  2230. {
  2231. pTemp = pValidate->dwhContext;
  2232. pValidate->dwhContext = (ULONG_PTR) pContext->dwhContext;
  2233. dwRet = OsThunkD3dValidateTextureStageState((D3DNTHAL_VALIDATETEXTURESTAGESTATEDATA*)pValidate);
  2234. pValidate->dwhContext = pTemp;
  2235. if (pValidate->ddrval == DDERR_SURFACELOST)
  2236. {
  2237. pValidate->ddrval = D3DERR_DEVICELOST;
  2238. }
  2239. }
  2240. return dwRet;
  2241. }
  2242. /******************************Public*Routine******************************\
  2243. *
  2244. * D3dDrawPrimitives2
  2245. *
  2246. * History:
  2247. * Mon Jun 17 13:27:05 1996 -by- Anantha Kancherla [anankan]
  2248. * Created
  2249. *
  2250. \**************************************************************************/
  2251. #undef DPF_MODNAME
  2252. #define DPF_MODNAME "D3dDrawPrimitives2"
  2253. DWORD WINAPI D3dDrawPrimitives2(PD3D8_DRAWPRIMITIVES2DATA pdp2data)
  2254. {
  2255. PD3DCONTEXTHANDLE pContext = (PD3DCONTEXTHANDLE) pdp2data->dwhContext;
  2256. DWORD dwRet = DDHAL_DRIVER_HANDLED;
  2257. ULONG_PTR pTemp;
  2258. if (CheckForDeviceLost (pContext->pDevice))
  2259. {
  2260. goto DeviceLost;
  2261. }
  2262. pTemp = pdp2data->dwhContext;
  2263. pdp2data->dwhContext = (ULONG_PTR) pContext->dwhContext;
  2264. if (pdp2data->dwFlags & D3DHALDP2_USERMEMVERTICES)
  2265. {
  2266. dwRet = OsThunkD3dDrawPrimitives2 (
  2267. GetSurfHandle(pdp2data->hDDCommands),
  2268. NULL, // No DDraw surface, pass NULL handle
  2269. (LPD3DNTHAL_DRAWPRIMITIVES2DATA)pdp2data,
  2270. &((PDDSURFHANDLE)(pdp2data->hDDCommands))->fpVidMem,
  2271. &((PDDSURFHANDLE)(pdp2data->hDDCommands))->dwLinearSize,
  2272. NULL,
  2273. NULL
  2274. );
  2275. if (dwRet == DDHAL_DRIVER_HANDLED)
  2276. {
  2277. if (pdp2data->ddrval == DDERR_SURFACELOST)
  2278. {
  2279. pdp2data->dwhContext = pTemp;
  2280. goto DeviceLost;
  2281. }
  2282. else if ((pdp2data->ddrval != S_OK) &&
  2283. (DDERR_WASSTILLDRAWING != pdp2data->ddrval) )
  2284. {
  2285. pContext->pDevice->dwFlags |= DDDEVICE_DP2ERROR;
  2286. }
  2287. }
  2288. pdp2data->fpVidMem_CB = ((PDDSURFHANDLE)(pdp2data->hDDCommands))->fpVidMem;
  2289. pdp2data->dwLinearSize_CB = ((PDDSURFHANDLE)(pdp2data->hDDCommands))->dwLinearSize;
  2290. pdp2data->fpVidMem_VB = 0;
  2291. pdp2data->dwLinearSize_VB = 0;
  2292. }
  2293. else
  2294. {
  2295. dwRet = OsThunkD3dDrawPrimitives2 (
  2296. GetSurfHandle(pdp2data->hDDCommands),
  2297. GetSurfHandle(pdp2data->hDDVertex),
  2298. (LPD3DNTHAL_DRAWPRIMITIVES2DATA)pdp2data,
  2299. &((PDDSURFHANDLE)(pdp2data->hDDCommands))->fpVidMem,
  2300. &((PDDSURFHANDLE)(pdp2data->hDDCommands))->dwLinearSize,
  2301. &((PDDSURFHANDLE)(pdp2data->hDDVertex))->fpVidMem,
  2302. &((PDDSURFHANDLE)(pdp2data->hDDVertex))->dwLinearSize
  2303. );
  2304. if (dwRet == DDHAL_DRIVER_HANDLED)
  2305. {
  2306. if (pdp2data->ddrval == DDERR_SURFACELOST)
  2307. {
  2308. pdp2data->dwhContext = pTemp;
  2309. goto DeviceLost;
  2310. }
  2311. else if ((pdp2data->ddrval != S_OK) &&
  2312. (DDERR_WASSTILLDRAWING != pdp2data->ddrval) )
  2313. {
  2314. pContext->pDevice->dwFlags |= DDDEVICE_DP2ERROR;
  2315. }
  2316. }
  2317. pdp2data->fpVidMem_CB = ((PDDSURFHANDLE)(pdp2data->hDDCommands))->fpVidMem;
  2318. pdp2data->dwLinearSize_CB = ((PDDSURFHANDLE)(pdp2data->hDDCommands))->dwLinearSize;
  2319. pdp2data->fpVidMem_VB = ((PDDSURFHANDLE)(pdp2data->hDDVertex))->fpVidMem;
  2320. pdp2data->dwLinearSize_VB = ((PDDSURFHANDLE)(pdp2data->hDDVertex))->dwLinearSize;
  2321. }
  2322. pdp2data->dwhContext = pTemp;
  2323. return dwRet;
  2324. DeviceLost:
  2325. pdp2data->ddrval = S_OK;
  2326. pdp2data->dwErrorOffset = 0;
  2327. // Need to set these values to their original
  2328. // state so that the FE doesn't get confused.
  2329. pdp2data->fpVidMem_CB = ((PDDSURFHANDLE)(pdp2data->hDDCommands))->fpVidMem;
  2330. pdp2data->dwLinearSize_CB = ((PDDSURFHANDLE)(pdp2data->hDDCommands))->dwLinearSize;
  2331. if (pdp2data->dwFlags & D3DHALDP2_USERMEMVERTICES)
  2332. {
  2333. pdp2data->fpVidMem_VB = 0;
  2334. pdp2data->dwLinearSize_VB = 0;
  2335. }
  2336. else
  2337. {
  2338. pdp2data->fpVidMem_VB = ((PDDSURFHANDLE)(pdp2data->hDDVertex))->fpVidMem;
  2339. pdp2data->dwLinearSize_VB = ((PDDSURFHANDLE)(pdp2data->hDDVertex))->dwLinearSize;
  2340. }
  2341. // Don't map the legacy result because the runtime needs to handle the
  2342. // WASSTILLDRAWING case. The runtime will do this mapping for us.
  2343. return DDHAL_DRIVER_HANDLED;
  2344. }
  2345. LPRGNDATA GetClipList(HWND hWnd)
  2346. {
  2347. int APIENTRY GetRandomRgn(HDC hdc, HRGN hrgn, int iNum);
  2348. int rc;
  2349. HRESULT ddrval = S_OK;
  2350. DWORD dwSize;
  2351. DWORD cbRealSize;
  2352. HDC hdc;
  2353. HRGN hrgn;
  2354. LPRGNDATA lpClipList;
  2355. hdc = GetDC(hWnd);
  2356. if (hdc == NULL)
  2357. {
  2358. DPF_ERR("GetDC failed. Unable to accelerate Present.");
  2359. return NULL;
  2360. }
  2361. // Create the appropriate Region object
  2362. hrgn = CreateRectRgn(0, 0, 0, 0);
  2363. if (hrgn == NULL)
  2364. {
  2365. DPF_ERR("CreateRectRgn failed. Unable to accelerate Present.");
  2366. ReleaseDC(hWnd, hdc);
  2367. return NULL;
  2368. }
  2369. // Set the Region to the DC
  2370. if (-1 == GetRandomRgn(hdc, hrgn, 4))
  2371. {
  2372. DPF_ERR("GetRandomRgn failed. Unable to accelerate Present.");
  2373. ReleaseDC(hWnd, hdc);
  2374. DeleteObject(hrgn);
  2375. return NULL;
  2376. }
  2377. // Get the size
  2378. dwSize = GetRegionData(hrgn, 0, NULL);
  2379. if (0 == dwSize)
  2380. {
  2381. // Release allocations
  2382. ReleaseDC(hWnd, hdc);
  2383. DeleteObject(hrgn);
  2384. return NULL;
  2385. }
  2386. do
  2387. {
  2388. lpClipList = (LPRGNDATA)MemAlloc(dwSize);
  2389. if (NULL == lpClipList)
  2390. {
  2391. // Release allocations
  2392. ReleaseDC(hWnd, hdc);
  2393. DeleteObject(hrgn);
  2394. return NULL;
  2395. }
  2396. // Get the window's region's REGIONDATA
  2397. cbRealSize = GetRegionData(hrgn, dwSize, lpClipList);
  2398. if (cbRealSize > dwSize)
  2399. {
  2400. MemFree(lpClipList);
  2401. dwSize = cbRealSize; // make it bigger and try again
  2402. }
  2403. else
  2404. {
  2405. break; // succeeded
  2406. }
  2407. }while(TRUE);
  2408. ReleaseDC(hWnd, hdc);
  2409. DeleteObject(hrgn);
  2410. if (cbRealSize == 0)
  2411. {
  2412. DPF_ERR("GetRegionData failed. Unable to accelerate Present.");
  2413. MemFree(lpClipList);
  2414. return NULL;
  2415. }
  2416. return lpClipList;
  2417. }
  2418. /*
  2419. * ClipRgnToRect
  2420. */
  2421. void ClipRgnToRect(LPRECT prect, LPRGNDATA prd)
  2422. {
  2423. RECT rect;
  2424. int i;
  2425. int n;
  2426. LPRECTL prectlD;
  2427. LPRECTL prectlS;
  2428. if (prect == NULL || prd == NULL)
  2429. {
  2430. return;
  2431. }
  2432. // If the bounding rect of the region is exactly equal to
  2433. // or inside of the Restricting rect then we know
  2434. // we don't have to do any more work.
  2435. //
  2436. // In the common case, the rcBound will be the client
  2437. // area of a window and so will the restricting rect.
  2438. if (prect->top <= prd->rdh.rcBound.top &&
  2439. prect->bottom >= prd->rdh.rcBound.bottom &&
  2440. prect->left <= prd->rdh.rcBound.left &&
  2441. prect->right >= prd->rdh.rcBound.right)
  2442. {
  2443. return;
  2444. }
  2445. // If the bounding rect doesn't equal the prect then
  2446. // we might have to do some clipping.
  2447. rect = *prect;
  2448. prectlD = (LPRECTL) prd->Buffer;
  2449. prectlS = (LPRECTL) prd->Buffer;
  2450. n = (int)prd->rdh.nCount;
  2451. for (i=0; i<n; i++)
  2452. {
  2453. prectlD->left = max(prectlS->left, rect.left);
  2454. prectlD->right = min(prectlS->right, rect.right);
  2455. prectlD->top = max(prectlS->top, rect.top);
  2456. prectlD->bottom= min(prectlS->bottom, rect.bottom);
  2457. prectlS++;
  2458. if ((prectlD->bottom - prectlD->top <= 0) ||
  2459. (prectlD->right - prectlD->left <= 0))
  2460. {
  2461. prd->rdh.nCount--; // dont count empty rect.
  2462. }
  2463. else
  2464. {
  2465. prectlD++;
  2466. }
  2467. }
  2468. return;
  2469. } /* ClipRgnToRect */
  2470. /*
  2471. * XformRect
  2472. *
  2473. * Transform a clipped rect in destination space to the corresponding clipped
  2474. * rect in src space. So, if we're stretching from src to dest, this yields
  2475. * the unstretched clipping rect in src space.
  2476. *
  2477. * PARAMETERS:
  2478. * prcSrc - unclipped rect in the source space
  2479. * prcDest - unclipped rect in the destination space
  2480. * prcClippedDest - the rect we want to transform
  2481. * prcClippedSrc - the resulting rect in the source space. return value.
  2482. * scale_x - 16.16 fixed point src/dest width ratio
  2483. * scale_y - 16.16 fixed point src/dest height ratio
  2484. *
  2485. * DESCRIPTION:
  2486. * Given an rect in source space and a rect in destination space, and a
  2487. * clipped rectangle in the destination space (prcClippedDest), return
  2488. * the rectangle in the source space (prcClippedSrc) that maps to
  2489. * prcClippedDest.
  2490. *
  2491. * Use 16.16 fixed point math for more accuracy. (Shift left, do math,
  2492. * shift back (w/ round))
  2493. *
  2494. * RETURNS:
  2495. * S_OK always. prcClippedSrc is the mapped rectangle.
  2496. *
  2497. */
  2498. HRESULT XformRect(RECT * prcSrc, RECT * prcDest, RECT * prcClippedDest,
  2499. RECT * prcClippedSrc, DWORD scale_x, DWORD scale_y)
  2500. {
  2501. /*
  2502. * This first calculation is done with fixed point arithmetic (16.16).
  2503. * The result is converted to (32.0) below. Scale back into source space
  2504. */
  2505. prcClippedSrc->left = (prcClippedDest->left - prcDest->left) * scale_x;
  2506. prcClippedSrc->right = (prcClippedDest->right - prcDest->left) * scale_x;
  2507. prcClippedSrc->top = (prcClippedDest->top - prcDest->top) * scale_y;
  2508. prcClippedSrc->bottom = (prcClippedDest->bottom - prcDest->top) * scale_y;
  2509. /*
  2510. * now round (adding 0x8000 rounds) and translate (offset by the
  2511. * src offset)
  2512. */
  2513. prcClippedSrc->left = (((DWORD)prcClippedSrc->left + 0x8000) >> 16) + prcSrc->left;
  2514. prcClippedSrc->right = (((DWORD)prcClippedSrc->right + 0x8000) >> 16) + prcSrc->left;
  2515. prcClippedSrc->top = (((DWORD)prcClippedSrc->top + 0x8000) >> 16) + prcSrc->top;
  2516. prcClippedSrc->bottom = (((DWORD)prcClippedSrc->bottom + 0x8000) >> 16) + prcSrc->top;
  2517. /*
  2518. * Check for zero-sized source rect dimensions and bump if necessary
  2519. */
  2520. if (prcClippedSrc->left == prcClippedSrc->right)
  2521. {
  2522. if (prcClippedSrc->right == prcSrc->right)
  2523. {
  2524. (prcClippedSrc->left)--;
  2525. }
  2526. else
  2527. {
  2528. (prcClippedSrc->right)++;
  2529. }
  2530. }
  2531. if (prcClippedSrc->top == prcClippedSrc->bottom)
  2532. {
  2533. if (prcClippedSrc->bottom == prcSrc->bottom)
  2534. {
  2535. (prcClippedSrc->top)--;
  2536. }
  2537. else
  2538. {
  2539. (prcClippedSrc->bottom)++;
  2540. }
  2541. }
  2542. return S_OK;
  2543. } /* XformRect */
  2544. /*****************************Private*Routine******************************\
  2545. * DdBlt
  2546. *
  2547. * History:
  2548. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  2549. * Wrote it.
  2550. * 31-Mar-2000 -by- Kan Qiu [kanqiu]
  2551. * Made it handle clipping case
  2552. \**************************************************************************/
  2553. #undef DPF_MODNAME
  2554. #define DPF_MODNAME "DdBlt"
  2555. #define SIZE_OF_A_CLIPLIST(lpRgn) \
  2556. (sizeof(RGNDATAHEADER)+sizeof(RECTL)*lpRgn->rdh.nCount)
  2557. DWORD
  2558. WINAPI
  2559. DdBlt(
  2560. PD3D8_BLTDATA pBlt
  2561. )
  2562. {
  2563. DDHAL_BLTDATA bd;
  2564. DWORD ret = DDHAL_DRIVER_NOTHANDLED;
  2565. PDDSURFHANDLE pDstSurf = (PDDSURFHANDLE) pBlt->hDestSurface;
  2566. PDDSURFHANDLE pSrcSurf = (PDDSURFHANDLE) pBlt->hSrcSurface;
  2567. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pBlt->hDD;
  2568. DWORD bltcaps;
  2569. if (CheckForDeviceLost (pBlt->hDD))
  2570. {
  2571. // Some blts should fail, others should succeed:
  2572. // persistant -> non persitant : OK
  2573. // persistant -> persitant : FAIL
  2574. // non persistant -> persistant : FAIL
  2575. // non persistant -> non persistant : OK
  2576. if (pDstSurf && ((pDstSurf->Pool == D3DPOOL_LOCALVIDMEM) ||
  2577. (pDstSurf->Pool == D3DPOOL_NONLOCALVIDMEM))
  2578. )
  2579. {
  2580. pBlt->ddRVal = S_OK;
  2581. }
  2582. else
  2583. {
  2584. pBlt->ddRVal = D3DERR_DEVICELOST;
  2585. }
  2586. return DDHAL_DRIVER_HANDLED;
  2587. }
  2588. ZeroMemory(&bd, sizeof bd);
  2589. bd.ddRVal = E_FAIL; // always assume error
  2590. // Just a colorfill?
  2591. #ifdef DEBUG
  2592. if ((pSrcSurf == NULL) && pDstSurf)
  2593. {
  2594. do
  2595. {
  2596. bd.dwFlags = pBlt->dwFlags & DDBLT_VALID;
  2597. bd.IsClipped = FALSE; // NT Kernel cannot handle it
  2598. bd.bltFX = pBlt->bltFX;
  2599. bd.rDest = pBlt->rDest;
  2600. ret = OsThunkDdBlt(GetSurfHandle(pBlt->hDestSurface),
  2601. 0,
  2602. (PDD_BLTDATA) &bd);
  2603. if (DDHAL_DRIVER_NOTHANDLED == ret)
  2604. {
  2605. DPF_ERR("Driver failed color-fill blt. SWAPEFFECT_DISCARD not being enforced.");
  2606. }
  2607. } while (bd.ddRVal == DDERR_WASSTILLDRAWING);
  2608. return S_OK;
  2609. }
  2610. #endif
  2611. // Are we going to send this blt to the driver?
  2612. if (!pDstSurf)
  2613. {
  2614. // NULL destination ? we are running SW driver w/o ddraw support
  2615. // use GDI for blting
  2616. goto gdiblt;
  2617. }
  2618. else if (IS_SOFTWARE_DRIVER_SURFACE(pSrcSurf))
  2619. {
  2620. if (!(pDevice->DDCaps & DDCAPS_CANBLTSYSMEM))
  2621. goto gdiblt;
  2622. bltcaps = pDevice->SVBCaps;
  2623. }
  2624. else
  2625. {
  2626. bltcaps = pDevice->DDCaps;
  2627. }
  2628. if (!(bltcaps & DDCAPS_BLT))
  2629. goto gdiblt;
  2630. //it is assumed that the format for a presented back buffer is OK and has
  2631. //been validated by higher layers of the runtime. (e.g. if the back
  2632. //buffer has alpha, or in the future is very different from front buffer format)
  2633. if ((pDstSurf->Format == pSrcSurf->Format) ||
  2634. (pBlt->dwFlags & DDBLT_WINDOWCLIP) ) //which means this is a presentation blt
  2635. {
  2636. //Yes, we're going to the driver...
  2637. bd.rDest = pBlt->rDest;
  2638. bd.rSrc = pBlt->rSrc;
  2639. bd.dwFlags = pBlt->dwFlags & DDBLT_VALID;
  2640. bd.dwROPFlags = pBlt->dwROPFlags;
  2641. bd.IsClipped = FALSE; // NT Kernel cannot handle it
  2642. bd.bltFX = pBlt->bltFX;
  2643. // This is for Window Redirection support
  2644. // (available on post-Windows 2000)
  2645. // On Windows 2000, bd.Blt is ignored by win32k.sys
  2646. if (pBlt->dwFlags & DDBLT_WINDOWCLIP)
  2647. {
  2648. bd.Blt = (VOID*)(pBlt->hWnd);
  2649. }
  2650. // Mask DX8 flags from the OS
  2651. if (pBlt->dwFlags & DDBLT_DX8ORHIGHER)
  2652. {
  2653. bd.dwFlags &= ~(DDBLT_WINDOWCLIP | DDBLT_COPYVSYNC | DDBLT_DX8ORHIGHER);
  2654. }
  2655. DPF(10,"pBlt->rDest %08lx %08lx %08lx %08lx",
  2656. pBlt->rDest.top, pBlt->rDest.bottom,
  2657. pBlt->rDest.left, pBlt->rDest.right);
  2658. if ((pBlt->hWnd) && (DDBLT_WINDOWCLIP & pBlt->dwFlags))
  2659. {
  2660. RECTL rOrigSrc=pBlt->rSrc; // unclipped src rect
  2661. LONG SrcWidth = rOrigSrc.right - rOrigSrc.left;
  2662. LONG SrcHeight = rOrigSrc.bottom - rOrigSrc.top;
  2663. RECT rOrigDest;
  2664. do
  2665. {
  2666. LPRGNDATA prd;
  2667. LPRECT prect;
  2668. DWORD cnt;
  2669. if (GetClientRect(pBlt->hWnd, &rOrigDest))
  2670. {
  2671. POINT pOrigDest;
  2672. if (rOrigDest.right > pBlt->rDest.right)
  2673. rOrigDest.right = pBlt->rDest.right;
  2674. if (rOrigDest.bottom > pBlt->rDest.bottom)
  2675. rOrigDest.bottom = pBlt->rDest.bottom;
  2676. if (0 < pBlt->rDest.left)
  2677. rOrigDest.left = pBlt->rDest.left;
  2678. if (0 < pBlt->rDest.top)
  2679. rOrigDest.top = pBlt->rDest.top;
  2680. if ((rOrigDest.right <= rOrigDest.left) ||
  2681. (rOrigDest.bottom <= rOrigDest.top)
  2682. )
  2683. {
  2684. pBlt->ddRVal = S_OK;
  2685. return DDHAL_DRIVER_HANDLED;
  2686. }
  2687. pOrigDest.x = - pDevice->rcMonitor.left;
  2688. pOrigDest.y = - pDevice->rcMonitor.top;
  2689. if (!ClientToScreen(pBlt->hWnd, &pOrigDest))
  2690. DPF_ERR("ClientToScreen Failed on pOrigDest?");
  2691. if (!OffsetRect(&rOrigDest, pOrigDest.x, pOrigDest.y ))
  2692. DPF_ERR("OffsetRect Failed on rOrigDest?");
  2693. if (rOrigDest.bottom <= 0 || rOrigDest.right <= 0 ||
  2694. (rOrigDest.top + pDevice->rcMonitor.top >= pDevice->rcMonitor.bottom) ||
  2695. (rOrigDest.left + pDevice->rcMonitor.left >= pDevice->rcMonitor.right))
  2696. {
  2697. // client is completely outside device space
  2698. // means cross device blt is needed
  2699. goto gdiblt;
  2700. }
  2701. }
  2702. else
  2703. {
  2704. DPF_ERR("GetClientRect Failed ?");
  2705. goto gdiblt;
  2706. }
  2707. if ( ( NULL == pDevice->pClipList )
  2708. || ( NULL == pDevice->pOrigClipList )
  2709. || ( pDevice->hLastWnd != pBlt->hWnd )
  2710. || (DDERR_VISRGNCHANGED == bd.ddRVal))
  2711. {
  2712. DWORD dwClipListSize;
  2713. if ( NULL != pDevice->pClipList )
  2714. {
  2715. MemFree(pDevice->pClipList);
  2716. pDevice->pClipList = NULL;
  2717. }
  2718. if ( NULL != pDevice->pOrigClipList )
  2719. {
  2720. MemFree(pDevice->pOrigClipList);
  2721. pDevice->pOrigClipList = NULL;
  2722. }
  2723. prd = GetClipList(pBlt->hWnd);
  2724. if (NULL == prd)
  2725. goto gdiblt;
  2726. prect=(LPRECT) &prd->Buffer[0];
  2727. for (cnt=0; cnt<prd->rdh.nCount; cnt++)
  2728. {
  2729. if ((prect[cnt].top < pDevice->rcMonitor.top) ||
  2730. (prect[cnt].left < pDevice->rcMonitor.left) ||
  2731. (prect[cnt].bottom > pDevice->rcMonitor.bottom) ||
  2732. (prect[cnt].right > pDevice->rcMonitor.right)
  2733. )
  2734. {
  2735. // do GDI blt if any rect is outside
  2736. MemFree (prd);
  2737. goto gdiblt;
  2738. }
  2739. if (!OffsetRect( &prect[cnt], - pDevice->rcMonitor.left,
  2740. - pDevice->rcMonitor.top ))
  2741. DPF_ERR("OffsetRect Failed on prect[cnt]?");
  2742. }
  2743. dwClipListSize = SIZE_OF_A_CLIPLIST(prd);
  2744. pDevice->pOrigClipList = (LPRGNDATA)MemAlloc(dwClipListSize);
  2745. if (NULL != pDevice->pOrigClipList)
  2746. {
  2747. memcpy(pDevice->pOrigClipList, prd, dwClipListSize);
  2748. pDevice->hLastWnd = pBlt->hWnd;
  2749. }
  2750. }
  2751. else
  2752. {
  2753. prd = pDevice->pClipList;
  2754. memcpy(prd, pDevice->pOrigClipList,
  2755. SIZE_OF_A_CLIPLIST(pDevice->pOrigClipList));
  2756. }
  2757. DDASSERT( (0 == pDevice->pClipList) || ( prd == pDevice->pClipList) );
  2758. DDASSERT( NULL != prd );
  2759. // Clip the region to the rect before we go further
  2760. ClipRgnToRect(&rOrigDest, prd );
  2761. // Process each visible sub-rect separately
  2762. if (prd->rdh.nCount > 0)
  2763. {
  2764. int x_offset;
  2765. int y_offset;
  2766. DWORD scale_x;
  2767. DWORD scale_y;
  2768. BOOL stretch_blt;
  2769. pDevice->pClipList = prd;
  2770. // precalculate a couple of variables
  2771. if ((rOrigDest.bottom - rOrigDest.top == SrcHeight) &&
  2772. (rOrigDest.right - rOrigDest.left == SrcWidth))
  2773. {
  2774. x_offset = rOrigSrc.left - rOrigDest.left;
  2775. y_offset = rOrigSrc.top - rOrigDest.top;
  2776. stretch_blt = FALSE;
  2777. }
  2778. else
  2779. {
  2780. if (!(bltcaps & DDCAPS_BLTSTRETCH))
  2781. goto gdiblt;
  2782. // scale_x and scale_y are fixed point variables scaled
  2783. // 16.16 (16 integer bits and 16 fractional bits)
  2784. scale_x = (SrcWidth << 16) /
  2785. (rOrigDest.right - rOrigDest.left);
  2786. scale_y = (SrcHeight << 16) /
  2787. (rOrigDest.bottom - rOrigDest.top);
  2788. stretch_blt = TRUE;
  2789. }
  2790. if (DDBLT_COPYVSYNC & pBlt->dwFlags)
  2791. {
  2792. DD_GETSCANLINEDATA ScanData;
  2793. DWORD msStartTime = GetTickCount();
  2794. DWORD msCurrentTime;
  2795. DWORD threshold=pBlt->threshold;
  2796. // Compute how many milliseconds there
  2797. // are per refresh. We round down.
  2798. msCurrentTime = msStartTime;
  2799. // If the previous blt was just a few ms ago
  2800. // then we can make up the difference by yielding
  2801. if ((msCurrentTime - pBlt->msLastPresent) < threshold )
  2802. {
  2803. Sleep(threshold + pBlt->msLastPresent - msCurrentTime);
  2804. msCurrentTime = pBlt->msLastPresent + threshold;
  2805. }
  2806. threshold = ((PDDSURFHANDLE)pBlt->hDestSurface)->dwHeight/2;
  2807. while (DDHAL_DRIVER_HANDLED ==
  2808. OsThunkDdGetScanLine(DDHANDLE(pBlt->hDD),&ScanData))
  2809. {
  2810. if (DD_OK != ScanData.ddRVal)
  2811. break;
  2812. if ((LONG)ScanData.dwScanLine >= rOrigDest.bottom)
  2813. break;
  2814. if ((LONG)(ScanData.dwScanLine + threshold/3) < rOrigDest.top)
  2815. break;
  2816. // just yield 1 ms instead of doing lengthy calculation which
  2817. // does not get me better result
  2818. if ((LONG)(ScanData.dwScanLine + threshold) < rOrigDest.bottom)
  2819. {
  2820. Sleep(1);
  2821. }
  2822. // If we've been spinning here for 30ms
  2823. // then blt anyway; probably something
  2824. // running in the background taking
  2825. // up CPU cycles
  2826. msCurrentTime = GetTickCount();
  2827. if ((msCurrentTime - msStartTime) > 30)
  2828. {
  2829. break;
  2830. }
  2831. }
  2832. // Remember the time of last blt
  2833. pBlt->msLastPresent = msCurrentTime;
  2834. }
  2835. //traverse the visible rect list and send each piece to
  2836. //the driver to blit
  2837. prect=(LPRECT) &prd->Buffer[0];
  2838. for (cnt=0;cnt<prd->rdh.nCount;cnt++)
  2839. {
  2840. // find out where on the src rect we need to get
  2841. // the data from.
  2842. bd.rDest.left = prect[cnt].left;
  2843. bd.rDest.right = prect[cnt].right;
  2844. bd.rDest.top = prect[cnt].top;
  2845. bd.rDest.bottom = prect[cnt].bottom;
  2846. if (!stretch_blt)
  2847. {
  2848. // no stretch
  2849. // one-to-one mapping from source to destination
  2850. bd.rSrc.left = bd.rDest.left + x_offset;
  2851. bd.rSrc.right = bd.rDest.right + x_offset;
  2852. bd.rSrc.top = bd.rDest.top + y_offset;
  2853. bd.rSrc.bottom = bd.rDest.bottom + y_offset;
  2854. }
  2855. else
  2856. {
  2857. // stretching
  2858. // linear mapping from source to destination
  2859. // calculate the source rect which transforms to the
  2860. // dest rect
  2861. XformRect((RECT *)&(rOrigSrc), &rOrigDest,
  2862. (RECT *)&(bd.rDest), (RECT *)&(bd.rSrc),
  2863. scale_x, scale_y);
  2864. }
  2865. // If mirror Blt, we must fix up source rect here!
  2866. if (bd.dwFlags & DDBLT_DDFX)
  2867. {
  2868. int temp;
  2869. if (bd.bltFX.dwDDFX & DDBLTFX_MIRRORLEFTRIGHT)
  2870. {
  2871. temp = bd.rSrc.left;
  2872. bd.rSrc.left = rOrigSrc.left +
  2873. rOrigSrc.right - bd.rSrc.right;
  2874. bd.rSrc.right = rOrigSrc.left +
  2875. rOrigSrc.right - temp;
  2876. }
  2877. if (bd.bltFX.dwDDFX & DDBLTFX_MIRRORUPDOWN)
  2878. {
  2879. temp = bd.rSrc.top;
  2880. bd.rSrc.top = rOrigSrc.top +
  2881. rOrigSrc.bottom - bd.rSrc.bottom;
  2882. bd.rSrc.bottom = rOrigSrc.top +
  2883. rOrigSrc.bottom - temp;
  2884. }
  2885. }
  2886. do
  2887. {
  2888. bd.ddRVal = E_FAIL; // always assume error
  2889. if (bd.dwFlags & DDBLT_PRESENTATION)
  2890. {
  2891. if (cnt == prd->rdh.nCount-1)
  2892. {
  2893. bd.dwFlags |= DDBLT_LAST_PRESENTATION;
  2894. }
  2895. }
  2896. ret = OsThunkDdBlt(GetSurfHandle(pBlt->hDestSurface),
  2897. GetSurfHandle(pBlt->hSrcSurface),
  2898. (PDD_BLTDATA) &bd);
  2899. if (DDHAL_DRIVER_NOTHANDLED == ret)
  2900. {
  2901. bd.ddRVal = E_FAIL; // make it out of loop
  2902. break;
  2903. }
  2904. if (bd.ddRVal == DDERR_SURFACELOST)
  2905. {
  2906. bd.ddRVal = S_OK;
  2907. break;
  2908. }
  2909. /*
  2910. * NOTE: If clipping has introduced more than
  2911. * one rectangle we behave as if DDBLT_WAIT
  2912. * was specified on all rectangles after the
  2913. * first. This is necessary as the first
  2914. * rectangle will probably cause the accelerator
  2915. * to be busy. Hence, the attempt to blit the
  2916. * second rectangle will fail with
  2917. * DDERR_WASSTILLDRAWING. If we pass this to
  2918. * the application (rather than busy waiting)
  2919. * the application is likely to retry the blit
  2920. * (which will fail on the second rectangle again)
  2921. * and we have an application sitting in an
  2922. * infinite loop).
  2923. */
  2924. } while( (DDERR_WASSTILLDRAWING == bd.ddRVal) &&
  2925. ( (DDBLT_WAIT & pBlt->dwFlags) ||
  2926. (1 < prd->rdh.nCount)
  2927. )
  2928. );
  2929. if (FAILED(bd.ddRVal))
  2930. break;
  2931. }
  2932. }
  2933. else
  2934. {
  2935. MemFree (prd);
  2936. pDevice->pClipList = NULL;
  2937. bd.ddRVal = S_OK;
  2938. ret = DDHAL_DRIVER_HANDLED;
  2939. break; // all clipped, no need to blt!
  2940. }
  2941. if (DDERR_VISRGNCHANGED == bd.ddRVal)
  2942. {
  2943. OsThunkDdResetVisrgn(GetSurfHandle(pBlt->hDestSurface),(HWND)0);
  2944. pDevice->hLastWnd = NULL; // zero cached info for DdBlt
  2945. }
  2946. } while (DDERR_VISRGNCHANGED == bd.ddRVal);
  2947. }
  2948. else
  2949. {
  2950. DDASSERT( 0 == (bd.dwFlags & DDBLT_PRESENTATION));
  2951. if ((bd.rDest.right - bd.rDest.left != bd.rSrc.right - bd.rSrc.left ||
  2952. bd.rDest.bottom - bd.rDest.top != bd.rSrc.bottom - bd.rSrc.top)
  2953. && !(bltcaps & DDCAPS_BLTSTRETCH)
  2954. )
  2955. goto gdiblt;
  2956. do
  2957. {
  2958. bd.ddRVal = E_FAIL; // always assume error
  2959. ret = OsThunkDdBlt(GetSurfHandle(pBlt->hDestSurface),
  2960. GetSurfHandle(pBlt->hSrcSurface),
  2961. (PDD_BLTDATA) &bd);
  2962. if (DDHAL_DRIVER_NOTHANDLED == ret)
  2963. {
  2964. bd.ddRVal = E_FAIL; // make it out of loop
  2965. break;
  2966. }
  2967. if (bd.ddRVal == DDERR_SURFACELOST)
  2968. {
  2969. bd.ddRVal = S_OK;
  2970. }
  2971. if (DDERR_VISRGNCHANGED == bd.ddRVal)
  2972. {
  2973. OsThunkDdResetVisrgn(GetSurfHandle(pBlt->hDestSurface),(HWND)0);
  2974. pDevice->hLastWnd = NULL; // zero cached info for DdBlt
  2975. }
  2976. } while ( (DDERR_VISRGNCHANGED == bd.ddRVal) ||
  2977. ( (DDERR_WASSTILLDRAWING == bd.ddRVal) &&
  2978. (DDBLT_WAIT & pBlt->dwFlags)
  2979. )
  2980. );
  2981. }
  2982. }
  2983. gdiblt:
  2984. if (FAILED(bd.ddRVal))
  2985. {
  2986. // !!! Just use GetDC on the DirectDraw surface for now, though this is
  2987. // probably way too slow on drivers which do not support derived
  2988. // surfaces. DirectDraw Blt support should be added soon.
  2989. HDC hDCTarget;
  2990. BOOL bGetDCfromWnd = (pBlt->hWnd) &&
  2991. ((DDBLT_WINDOWCLIP & pBlt->dwFlags) || !pBlt->hDestSurface);
  2992. if (bGetDCfromWnd)
  2993. hDCTarget = GetDC(pBlt->hWnd);
  2994. else
  2995. hDCTarget = D3D8GetDC(pBlt->hDestSurface, NULL);
  2996. if (hDCTarget != NULL)
  2997. {
  2998. HDC hDCSource = D3D8GetDC(pBlt->hSrcSurface, NULL);
  2999. if (hDCSource != NULL)
  3000. {
  3001. LONG DestWidth=pBlt->rDest.right - pBlt->rDest.left;
  3002. LONG DestHeight= pBlt->rDest.bottom - pBlt->rDest.top;
  3003. LONG SrcWidth= pBlt->rSrc.right - pBlt->rSrc.left;
  3004. LONG SrcHeight= pBlt->rSrc.bottom - pBlt->rSrc.top;
  3005. if (DestWidth == SrcWidth && DestHeight == SrcHeight)
  3006. {
  3007. if (BitBlt(
  3008. hDCTarget,
  3009. pBlt->rDest.left,
  3010. pBlt->rDest.top,
  3011. DestWidth,
  3012. DestHeight,
  3013. hDCSource,
  3014. pBlt->rSrc.left,
  3015. pBlt->rSrc.top,
  3016. SRCCOPY))
  3017. {
  3018. bd.ddRVal = S_OK;
  3019. ret = DDHAL_DRIVER_HANDLED;
  3020. }
  3021. }
  3022. else
  3023. {
  3024. // COLORONCOLOR is not the default in NT
  3025. int saved = SetStretchBltMode(hDCTarget,COLORONCOLOR);
  3026. if (StretchBlt(
  3027. hDCTarget,
  3028. pBlt->rDest.left,
  3029. pBlt->rDest.top,
  3030. DestWidth,
  3031. DestHeight,
  3032. hDCSource,
  3033. pBlt->rSrc.left,
  3034. pBlt->rSrc.top,
  3035. SrcWidth,
  3036. SrcHeight,
  3037. SRCCOPY))
  3038. {
  3039. bd.ddRVal = S_OK;
  3040. ret = DDHAL_DRIVER_HANDLED;
  3041. }
  3042. // restore to previous mode
  3043. if (saved)
  3044. SetStretchBltMode(hDCTarget,saved);
  3045. }
  3046. D3D8ReleaseDC(pBlt->hSrcSurface, hDCSource);
  3047. }
  3048. if (bGetDCfromWnd)
  3049. ReleaseDC(pBlt->hWnd, hDCTarget);
  3050. else
  3051. D3D8ReleaseDC(pBlt->hDestSurface, hDCTarget);
  3052. }
  3053. }
  3054. pBlt->ddRVal = MapLegacyResult(bd.ddRVal);
  3055. // We only want to report DP2 errors during the present call because
  3056. // checking for it everywhere is too hard.
  3057. if ((pBlt->ddRVal == DD_OK) &&
  3058. (pDevice->dwFlags & DDDEVICE_DP2ERROR) &&
  3059. (pBlt->dwFlags & DDBLT_WINDOWCLIP))
  3060. {
  3061. pDevice->dwFlags &= ~DDDEVICE_DP2ERROR;
  3062. // We use a special error here to mean that the blt succeeded
  3063. // but that that some DP2 failed since the last present
  3064. pBlt->ddRVal = D3DERR_DEFERRED_DP2ERROR;
  3065. }
  3066. return ret;
  3067. }
  3068. /*****************************Private*Routine******************************\
  3069. * DdFlip
  3070. *
  3071. * History:
  3072. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  3073. * Wrote it.
  3074. \**************************************************************************/
  3075. #undef DPF_MODNAME
  3076. #define DPF_MODNAME "DdFlip"
  3077. DWORD
  3078. APIENTRY
  3079. DdFlip(
  3080. PD3D8_FLIPDATA pFlip
  3081. )
  3082. {
  3083. HANDLE hSurfTargLeft=NULL;
  3084. HANDLE hSurfCurrLeft=NULL;
  3085. DDHAL_FLIPDATA FlipData;
  3086. DWORD dwRet;
  3087. if (CheckForDeviceLost (pFlip->hDD))
  3088. {
  3089. pFlip->ddRVal = S_OK;
  3090. return DDHAL_DRIVER_HANDLED;
  3091. }
  3092. FlipData.dwFlags = (pFlip->dwFlags & ~DDFLIP_WAIT);
  3093. FlipData.ddRVal = DDERR_GENERIC;
  3094. if (pFlip->dwFlags & DDFLIP_STEREO)
  3095. {
  3096. hSurfTargLeft = GetSurfHandle(pFlip->hSurfTargLeft);
  3097. hSurfCurrLeft = GetSurfHandle(pFlip->hSurfCurrLeft);
  3098. }
  3099. do
  3100. {
  3101. dwRet = OsThunkDdFlip(GetSurfHandle(pFlip->hSurfCurr),
  3102. GetSurfHandle(pFlip->hSurfTarg),
  3103. hSurfCurrLeft,
  3104. hSurfTargLeft,
  3105. (PDD_FLIPDATA) &FlipData);
  3106. if (FlipData.ddRVal == DDERR_SURFACELOST)
  3107. {
  3108. FlipData.ddRVal = S_OK;
  3109. }
  3110. }while (DDERR_WASSTILLDRAWING == FlipData.ddRVal &&
  3111. (DDFLIP_WAIT & pFlip->dwFlags));
  3112. pFlip->ddRVal = MapLegacyResult(FlipData.ddRVal);
  3113. // We only want to report DP2 errors during the present call because
  3114. // checking for it everywhere is too hard.
  3115. if ((pFlip->ddRVal == DD_OK) &&
  3116. (((DDDEVICEHANDLE*)pFlip->hDD)->dwFlags & DDDEVICE_DP2ERROR))
  3117. {
  3118. ((DDDEVICEHANDLE*)pFlip->hDD)->dwFlags &= ~DDDEVICE_DP2ERROR;
  3119. // We use a special error here to mean that the flip succeeded
  3120. // but that that some DP2 failed since the last present
  3121. pFlip->ddRVal = D3DERR_DEFERRED_DP2ERROR;
  3122. }
  3123. return dwRet;
  3124. }
  3125. /*****************************Private*Routine******************************\
  3126. * DdLock
  3127. *
  3128. * History:
  3129. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  3130. * Wrote it.
  3131. \**************************************************************************/
  3132. #undef DPF_MODNAME
  3133. #define DPF_MODNAME "DdLock"
  3134. HRESULT
  3135. APIENTRY
  3136. DdLock(
  3137. PD3D8_LOCKDATA pLock
  3138. )
  3139. {
  3140. DD_LOCKDATA LockData;
  3141. PDDSURFHANDLE pSurf;
  3142. BOOL bAdjustSlice = FALSE;
  3143. pSurf = (PDDSURFHANDLE) pLock->hSurface;
  3144. // If the device is lost, we need to fake up a buffer for
  3145. // the app to write to. We still allow software drivers
  3146. // handle the Lock call, however. Further, we also allow
  3147. // driver managed surfaces to go through.
  3148. if (CheckForDeviceLost (pLock->hDD) &&
  3149. !IS_SOFTWARE_DRIVER_SURFACE(pSurf) &&
  3150. pSurf->Pool != D3DPOOL_MANAGED)
  3151. {
  3152. goto DeviceLost;
  3153. }
  3154. // We do make an exception for fake deferred creates
  3155. // of driver managed surfaces. The driver doesn't know
  3156. // about these deferred surfaces, so we don't call it.
  3157. // ASSUMPTIONS: even if DDSURF_SYSMEMALLOCATED can be
  3158. // set below, we expect it to be never set below for
  3159. // **driver managed surfaces**. For these surfaces, we
  3160. // assume that it will be set only in
  3161. // CreateVidMemSurface. This assumption is true as of
  3162. // 3/2001.
  3163. if ((pSurf->dwFlags & DDSURF_SYSMEMALLOCATED) != 0)
  3164. {
  3165. DDASSERT(pSurf->fpVidMem != (ULONG_PTR)NULL);
  3166. goto DeviceLost;
  3167. }
  3168. // Mask off new flags
  3169. LockData.dwFlags = pLock->dwFlags;
  3170. LockData.dwFlags &= (D3DLOCK_READONLY |
  3171. D3DLOCK_DISCARD |
  3172. D3DLOCK_NOOVERWRITE |
  3173. D3DLOCK_NOSYSLOCK);
  3174. // Always set lock_wait
  3175. LockData.dwFlags |= DDLOCK_WAIT;
  3176. // Also set equivalent DDLOCK flag for NO_DIRTY_UPDATE
  3177. // if the driver understands it
  3178. if ((pLock->dwFlags & D3DLOCK_NO_DIRTY_UPDATE) != 0)
  3179. {
  3180. LockData.dwFlags |= DDLOCK_NODIRTYUPDATE;
  3181. }
  3182. if(pLock->bHasRange)
  3183. {
  3184. LockData.bHasRect = TRUE;
  3185. LockData.rArea.left = 0;
  3186. LockData.rArea.right = 0;
  3187. LockData.rArea.top = pLock->range.Offset;
  3188. LockData.rArea.bottom = pLock->range.Offset + pLock->range.Size;
  3189. }
  3190. else
  3191. {
  3192. LockData.bHasRect = pLock->bHasRect;
  3193. LockData.rArea = pLock->rArea;
  3194. }
  3195. if (pLock->bHasBox)
  3196. {
  3197. LockData.bHasRect = TRUE;
  3198. LockData.rArea.left = pLock->box.Left;
  3199. LockData.rArea.right = pLock->box.Right;
  3200. LockData.rArea.top = pLock->box.Top;
  3201. LockData.rArea.bottom = pLock->box.Bottom;
  3202. // We cannot change the kernel for an OS before whistler, so we will
  3203. // not pass the front/back to the driver. For ref and for newer OSes,
  3204. // we will stick the front/back into the high word of left/right
  3205. if (IS_SOFTWARE_DRIVER_SURFACE(pSurf) ||
  3206. ((((PDDDEVICEHANDLE)pLock->hDD)->bIsWhistler) &&
  3207. (((PDDDEVICEHANDLE)pLock->hDD)->dwFlags & DDDEVICE_SUPPORTSUBVOLUMELOCK)))
  3208. {
  3209. LockData.dwFlags |= DDLOCK_HASVOLUMETEXTUREBOXRECT;
  3210. LockData.rArea.left |= (pLock->box.Front << 16);
  3211. LockData.rArea.right |= (pLock->box.Back << 16);
  3212. }
  3213. else
  3214. {
  3215. bAdjustSlice = TRUE;
  3216. }
  3217. }
  3218. LockData.ddRVal = DDERR_WASSTILLDRAWING;
  3219. if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  3220. {
  3221. // This is a software driver, so we need to treat
  3222. // it specially
  3223. SwDDILock (pLock->hDD, pSurf, &LockData);
  3224. }
  3225. else
  3226. {
  3227. while ((LockData.ddRVal == DDERR_VISRGNCHANGED) ||
  3228. (LockData.ddRVal == DDERR_WASSTILLDRAWING))
  3229. {
  3230. if ((pSurf->Type == D3DRTYPE_VERTEXBUFFER) ||
  3231. (pSurf->Type == D3DRTYPE_COMMANDBUFFER)||
  3232. (pSurf->Type == D3DRTYPE_INDEXBUFFER))
  3233. {
  3234. OsThunkDdLockD3D(pSurf->hSurface,
  3235. &LockData);
  3236. }
  3237. else
  3238. {
  3239. OsThunkDdLock(pSurf->hSurface,
  3240. &LockData,
  3241. NULL);
  3242. }
  3243. if (LockData.ddRVal == DDERR_VISRGNCHANGED)
  3244. {
  3245. if (pLock->dwFlags & DDLOCK_FAILONVISRGNCHANGED)
  3246. {
  3247. break;
  3248. }
  3249. else
  3250. {
  3251. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pLock->hDD;
  3252. OsThunkDdResetVisrgn(pSurf->hSurface, (HWND)0);
  3253. pDevice->hLastWnd = NULL; // zero cached info for DdBlt
  3254. }
  3255. }
  3256. // In the past we would require DDLOCK_WAIT to
  3257. // decide if we would spin or exit now we always wait
  3258. }
  3259. if (LockData.ddRVal == DDERR_SURFACELOST)
  3260. {
  3261. CheckForDeviceLost(pLock->hDD);
  3262. goto DeviceLost;
  3263. }
  3264. }
  3265. if (LockData.ddRVal == S_OK)
  3266. {
  3267. pLock->lpSurfData = LockData.lpSurfData;
  3268. pLock->lPitch = pSurf->lPitch;
  3269. if ((pSurf->Type == D3DRTYPE_VOLUME) ||
  3270. (pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
  3271. {
  3272. pLock->lSlicePitch = pSurf->lSlicePitch;
  3273. if (bAdjustSlice)
  3274. {
  3275. ((BYTE*)pLock->lpSurfData) += (pLock->lSlicePitch *
  3276. pLock->box.Front);
  3277. }
  3278. }
  3279. pSurf->LockRefCnt++;
  3280. }
  3281. return MapLegacyResult(LockData.ddRVal);
  3282. DeviceLost:
  3283. // At the time the device is lost, fpVidMem is set to NULL
  3284. // for all vidmem surfaces. Therefore, if it is non-NULL
  3285. // we are safe to use what we already have; otherwise, we
  3286. // have to allocate our own.
  3287. if (pSurf->fpVidMem == (ULONG_PTR) NULL)
  3288. {
  3289. if ((pSurf->Type == D3DRTYPE_VOLUME) ||
  3290. (pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
  3291. {
  3292. // For volume textures, dwHeight really contains the depth
  3293. pSurf->fpVidMem = (ULONG_PTR) MemAlloc(pSurf->lSlicePitch * pSurf->dwHeight);
  3294. }
  3295. else
  3296. {
  3297. pSurf->fpVidMem = (ULONG_PTR) MemAlloc(pSurf->lPitch * pSurf->dwHeight);
  3298. }
  3299. if (pSurf->fpVidMem == (ULONG_PTR) NULL)
  3300. {
  3301. pLock->lpSurfData = (void*)pSurf->fpVidMem;
  3302. return E_FAIL;
  3303. }
  3304. pSurf->dwFlags |= DDSURF_SYSMEMALLOCATED;
  3305. }
  3306. pLock->lpSurfData = (void*)pSurf->fpVidMem;
  3307. pLock->lPitch = pSurf->lPitch;
  3308. if ((pSurf->Type == D3DRTYPE_VOLUME) ||
  3309. (pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
  3310. {
  3311. pLock->lSlicePitch = pSurf->lSlicePitch;
  3312. }
  3313. pSurf->LockRefCnt++;
  3314. return S_OK;
  3315. }
  3316. /*****************************Private*Routine******************************\
  3317. * DdUnlock
  3318. *
  3319. * History:
  3320. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  3321. * Wrote it.
  3322. \**************************************************************************/
  3323. #undef DPF_MODNAME
  3324. #define DPF_MODNAME "DdUnlock"
  3325. HRESULT
  3326. APIENTRY
  3327. DdUnlock(
  3328. PD3D8_UNLOCKDATA pUnlock
  3329. )
  3330. {
  3331. DD_UNLOCKDATA UnlockData;
  3332. PDDSURFHANDLE pSurf;
  3333. pSurf = (PDDSURFHANDLE) pUnlock->hSurface;
  3334. if (pSurf->LockRefCnt > 0)
  3335. {
  3336. pSurf->LockRefCnt--;
  3337. }
  3338. if (CheckForDeviceLost (pUnlock->hDD) &&
  3339. !IS_SOFTWARE_DRIVER_SURFACE(pSurf) &&
  3340. pSurf->Pool != D3DPOOL_MANAGED)
  3341. {
  3342. return S_OK;
  3343. }
  3344. if ((pSurf->dwFlags & DDSURF_SYSMEMALLOCATED) != 0)
  3345. {
  3346. DDASSERT(pSurf->fpVidMem != (ULONG_PTR)NULL);
  3347. return S_OK;
  3348. }
  3349. if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
  3350. {
  3351. // This is a software driver, so we need to treat
  3352. // it specially
  3353. SwDDIUnlock (pUnlock->hDD, pSurf, &UnlockData);
  3354. }
  3355. else
  3356. {
  3357. if ((GetSurfType(pUnlock->hSurface) == D3DRTYPE_VERTEXBUFFER) ||
  3358. (GetSurfType(pUnlock->hSurface) == D3DRTYPE_COMMANDBUFFER) ||
  3359. (GetSurfType(pUnlock->hSurface) == D3DRTYPE_INDEXBUFFER))
  3360. {
  3361. OsThunkDdUnlockD3D(GetSurfHandle(pUnlock->hSurface),
  3362. &UnlockData);
  3363. }
  3364. else
  3365. {
  3366. OsThunkDdUnlock(GetSurfHandle(pUnlock->hSurface),
  3367. &UnlockData);
  3368. }
  3369. if (UnlockData.ddRVal == DDERR_SURFACELOST)
  3370. {
  3371. UnlockData.ddRVal = S_OK;
  3372. }
  3373. }
  3374. return MapLegacyResult(UnlockData.ddRVal);
  3375. }
  3376. /*****************************Private*Routine******************************\
  3377. * DdGetBltStatus
  3378. *
  3379. * History:
  3380. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  3381. * Wrote it.
  3382. \**************************************************************************/
  3383. #undef DPF_MODNAME
  3384. #define DPF_MODNAME "DdGetBltStatus"
  3385. DWORD
  3386. APIENTRY
  3387. DdGetBltStatus(
  3388. PD3D8_GETBLTSTATUSDATA pGetBltStatus
  3389. )
  3390. {
  3391. DDHAL_GETBLTSTATUSDATA StatusData;
  3392. DWORD dwRet;
  3393. if (CheckForDeviceLost (pGetBltStatus->hDD))
  3394. {
  3395. pGetBltStatus->ddRVal = S_OK;
  3396. return DDHAL_DRIVER_HANDLED;
  3397. }
  3398. StatusData.dwFlags = pGetBltStatus->dwFlags;
  3399. dwRet = OsThunkDdGetBltStatus(GetSurfHandle(pGetBltStatus->hSurface),
  3400. (PDD_GETBLTSTATUSDATA) &StatusData);
  3401. if (StatusData.ddRVal == DDERR_SURFACELOST)
  3402. {
  3403. StatusData.ddRVal = S_OK;
  3404. }
  3405. pGetBltStatus->ddRVal = MapLegacyResult(StatusData.ddRVal);
  3406. return dwRet;
  3407. }
  3408. /*****************************Private*Routine******************************\
  3409. * DdGetFlipStatus
  3410. *
  3411. * History:
  3412. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  3413. * Wrote it.
  3414. \**************************************************************************/
  3415. #undef DPF_MODNAME
  3416. #define DPF_MODNAME "DdGetFlipStatus"
  3417. DWORD
  3418. APIENTRY
  3419. DdGetFlipStatus(
  3420. PD3D8_GETFLIPSTATUSDATA pGetFlipStatus
  3421. )
  3422. {
  3423. DDHAL_GETFLIPSTATUSDATA StatusData;
  3424. DWORD dwRet;
  3425. if (CheckForDeviceLost (pGetFlipStatus->hDD))
  3426. {
  3427. pGetFlipStatus->ddRVal = S_OK;
  3428. return DDHAL_DRIVER_HANDLED;
  3429. }
  3430. StatusData.dwFlags = pGetFlipStatus->dwFlags;
  3431. dwRet = OsThunkDdGetFlipStatus(GetSurfHandle(pGetFlipStatus->hSurface),
  3432. (PDD_GETFLIPSTATUSDATA) &StatusData);
  3433. if (StatusData.ddRVal == DDERR_SURFACELOST)
  3434. {
  3435. StatusData.ddRVal = S_OK;
  3436. }
  3437. pGetFlipStatus->ddRVal = MapLegacyResult(StatusData.ddRVal);
  3438. return dwRet;
  3439. }
  3440. /*****************************Private*Routine******************************\
  3441. * DdWaitForVerticalBlank
  3442. *
  3443. * History:
  3444. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  3445. * Wrote it.
  3446. \**************************************************************************/
  3447. #undef DPF_MODNAME
  3448. #define DPF_MODNAME "DdWaitForVerticalBlank"
  3449. DWORD
  3450. APIENTRY
  3451. DdWaitForVerticalBlank(
  3452. PD3D8_WAITFORVERTICALBLANKDATA pWaitForVerticalBlank
  3453. )
  3454. {
  3455. DDHAL_WAITFORVERTICALBLANKDATA WaitData;
  3456. DWORD dwRet;
  3457. if (CheckForDeviceLost (pWaitForVerticalBlank->hDD))
  3458. {
  3459. goto DeviceLost;
  3460. }
  3461. WaitData.dwFlags = pWaitForVerticalBlank->dwFlags;
  3462. WaitData.hEvent = 0;
  3463. dwRet = OsThunkDdWaitForVerticalBlank(DDHANDLE(pWaitForVerticalBlank->hDD),
  3464. (PDD_WAITFORVERTICALBLANKDATA) &WaitData);
  3465. if (WaitData.ddRVal == DDERR_SURFACELOST)
  3466. {
  3467. goto DeviceLost;
  3468. }
  3469. pWaitForVerticalBlank->bIsInVB = WaitData.bIsInVB;
  3470. pWaitForVerticalBlank->ddRVal = WaitData.ddRVal;
  3471. if (WaitData.ddRVal == DDERR_VERTICALBLANKINPROGRESS)
  3472. {
  3473. pWaitForVerticalBlank->bIsInVB = TRUE;
  3474. }
  3475. else
  3476. {
  3477. pWaitForVerticalBlank->bIsInVB = FALSE;
  3478. }
  3479. pWaitForVerticalBlank->ddRVal = DD_OK;
  3480. return dwRet;
  3481. DeviceLost:
  3482. {
  3483. static int LostTestVerticalBlank;
  3484. pWaitForVerticalBlank->ddRVal = DD_OK;
  3485. if (pWaitForVerticalBlank->dwFlags == DDWAITVB_I_TESTVB)
  3486. {
  3487. if (LostTestVerticalBlank > 0)
  3488. {
  3489. pWaitForVerticalBlank->bIsInVB = TRUE;
  3490. }
  3491. else
  3492. {
  3493. pWaitForVerticalBlank->bIsInVB = FALSE;
  3494. }
  3495. LostTestVerticalBlank = LostTestVerticalBlank == 0 ? 1 : 0;
  3496. }
  3497. else if (pWaitForVerticalBlank->dwFlags == DDWAITVB_BLOCKEND)
  3498. {
  3499. pWaitForVerticalBlank->bIsInVB = FALSE;
  3500. }
  3501. else
  3502. {
  3503. pWaitForVerticalBlank->bIsInVB = TRUE;
  3504. }
  3505. }
  3506. return DDHAL_DRIVER_HANDLED;
  3507. }
  3508. /*****************************Private*Routine******************************\
  3509. * DdDestroySurface
  3510. *
  3511. * History:
  3512. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  3513. * Wrote it.
  3514. \**************************************************************************/
  3515. #undef DPF_MODNAME
  3516. #define DPF_MODNAME "DdDestroySurface"
  3517. DWORD
  3518. APIENTRY
  3519. DdDestroySurface(
  3520. PD3D8_DESTROYSURFACEDATA pDestroySurface
  3521. )
  3522. {
  3523. DWORD i;
  3524. PDDSURFHANDLE pSurf = (PDDSURFHANDLE) pDestroySurface->hSurface;
  3525. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pDestroySurface->hDD;
  3526. PDEFERREDCREATE pDefCreate = pDevice->pDeferList;
  3527. FreeSurfaceObject(pSurf);
  3528. // Remove the surface from the linked list
  3529. if (pDevice->pSurfList == pSurf)
  3530. {
  3531. pDevice->pSurfList = pSurf->pNext;
  3532. if (pSurf->pNext != NULL)
  3533. {
  3534. pSurf->pNext->pPrevious = NULL;
  3535. }
  3536. }
  3537. else
  3538. {
  3539. if (pSurf->pNext != NULL)
  3540. {
  3541. pSurf->pNext->pPrevious = pSurf->pPrevious;
  3542. }
  3543. pSurf->pPrevious->pNext = pSurf->pNext;
  3544. }
  3545. // If we allcoated the memory for this surface (due to a lost state),
  3546. // then we should free it now.
  3547. if (pSurf->dwFlags & DDSURF_SYSMEMALLOCATED)
  3548. {
  3549. MemFree((void*) pSurf->fpVidMem);
  3550. }
  3551. // If this surface pointer is cached in the context structure, we need
  3552. // to remedy that.
  3553. if (pSurf->pDevice->pContext != NULL)
  3554. {
  3555. if (pSurf->pDevice->pContext->pSurface == pSurf)
  3556. {
  3557. pSurf->pDevice->pContext->pSurface = NULL;
  3558. }
  3559. if (pSurf->pDevice->pContext->pDDSZ == pSurf)
  3560. {
  3561. pSurf->pDevice->pContext->pDDSZ = NULL;
  3562. }
  3563. }
  3564. MemFree (pSurf);
  3565. // We look in the defer list to see if any referenced surface
  3566. // is being destroyed. If this is the case, then we need to
  3567. // update the defer list and mark the surfaces as freed so
  3568. // that we don't try and resurrect destroyed surfaces. Although
  3569. // this appears slow, it is not too bad because a deferred list
  3570. // will be present only if a mode switch happened. In this case,
  3571. // it doesn't hurt if things are a little slow.
  3572. while (pDefCreate != NULL)
  3573. {
  3574. for (i = 0; i < pDefCreate->CreateData.dwSCnt; i++)
  3575. {
  3576. if (pSurf == (PDDSURFHANDLE) pDefCreate->CreateData.pSList[i].hKernelHandle)
  3577. {
  3578. pDefCreate->CreateData.pSList[i].hKernelHandle = 0;
  3579. break;
  3580. }
  3581. }
  3582. pDefCreate = pDefCreate->pNext;
  3583. }
  3584. return (DDHAL_DRIVER_HANDLED);
  3585. }
  3586. #undef DPF_MODNAME
  3587. #define DPF_MODNAME "D3D8GetMode"
  3588. DWORD
  3589. APIENTRY
  3590. D3D8GetMode(
  3591. HANDLE Handle,
  3592. char* pDeviceName,
  3593. D3DDISPLAYMODE* pMode,
  3594. D3DFORMAT Unknown16)
  3595. {
  3596. DEVMODE dm;
  3597. HDC hdc;
  3598. memset (&dm, 0, sizeof(dm));
  3599. dm.dmSize = sizeof(dm);
  3600. if (EnumDisplaySettings(pDeviceName, ENUM_CURRENT_SETTINGS, &dm))
  3601. {
  3602. pMode->Width = dm.dmPelsWidth;
  3603. pMode->Height = dm.dmPelsHeight;
  3604. pMode->RefreshRate = dm.dmDisplayFrequency;
  3605. switch (dm.dmBitsPerPel)
  3606. {
  3607. case 8:
  3608. pMode->Format = D3DFMT_P8;
  3609. break;
  3610. case 24:
  3611. pMode->Format = D3DFMT_R8G8B8;
  3612. break;
  3613. case 32:
  3614. pMode->Format = D3DFMT_X8R8G8B8;
  3615. break;
  3616. case 15:
  3617. case 16:
  3618. pMode->Format = D3DFMT_R5G6B5;
  3619. hdc = DD_CreateDC(pDeviceName);
  3620. if (hdc)
  3621. {
  3622. HBITMAP hbm;
  3623. BITMAPINFO *pbmi;
  3624. DWORD *pdwColors;
  3625. if (pbmi = (BITMAPINFO*) MemAlloc(3 * sizeof (RGBQUAD) + sizeof (BITMAPINFO)))
  3626. {
  3627. if (hbm = CreateCompatibleBitmap(hdc, 1, 1))
  3628. {
  3629. pbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
  3630. if (GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS))
  3631. {
  3632. if (pbmi->bmiHeader.biCompression == BI_BITFIELDS)
  3633. {
  3634. GetDIBits(hdc, hbm, 0, pbmi->bmiHeader.biHeight,
  3635. NULL, pbmi, DIB_RGB_COLORS);
  3636. pdwColors = (DWORD *) &pbmi->bmiColors[0];
  3637. if (pdwColors[1] == 0x3e0)
  3638. {
  3639. pMode->Format = D3DFMT_X1R5G5B5;
  3640. }
  3641. }
  3642. }
  3643. DeleteObject(hbm);
  3644. }
  3645. MemFree(pbmi);
  3646. }
  3647. DD_DoneDC(hdc);
  3648. }
  3649. break;
  3650. default:
  3651. pMode->Format = D3DFMT_UNKNOWN;
  3652. break;
  3653. }
  3654. return S_OK;
  3655. }
  3656. // I don't know in which cases we would ever hit this
  3657. return D3DERR_DRIVERINTERNALERROR;
  3658. }
  3659. #undef DPF_MODNAME
  3660. #define DPF_MODNAME "D3D8SetMode"
  3661. DWORD
  3662. APIENTRY
  3663. D3D8SetMode(
  3664. HANDLE Handle,
  3665. char* pDeviceName,
  3666. UINT Width,
  3667. UINT Height,
  3668. UINT BPP,
  3669. UINT RefreshRate,
  3670. BOOL bRestore)
  3671. {
  3672. HANDLE h = GetModuleHandle("USER32");
  3673. LONG (WINAPI *pfnChangeDisplaySettingsExA)(LPCSTR,LPDEVMODEA,HWND,DWORD,LPVOID);
  3674. DEVMODE dm, * pdm;
  3675. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) Handle;
  3676. // Init the devmode properly:
  3677. dm.dmSize = sizeof(DEVMODE);
  3678. EnumDisplaySettings (pDeviceName,0,&dm);
  3679. dm.dmBitsPerPel = BPP;
  3680. dm.dmPelsWidth = Width;
  3681. dm.dmPelsHeight = Height;
  3682. dm.dmDisplayFrequency = RefreshRate;
  3683. dm.dmDisplayFlags = 0;
  3684. dm.dmFields = DM_BITSPERPEL |
  3685. DM_PELSWIDTH |
  3686. DM_PELSHEIGHT |
  3687. DM_DISPLAYFREQUENCY;
  3688. // Now tell the OS to do the mode change
  3689. (FARPROC)pfnChangeDisplaySettingsExA = GetProcAddress(h,"ChangeDisplaySettingsExA");
  3690. if (pfnChangeDisplaySettingsExA)
  3691. {
  3692. InformDriverToDeferFrees(pDevice);
  3693. if (bRestore)
  3694. {
  3695. if ((*pfnChangeDisplaySettingsExA)(pDeviceName,
  3696. NULL, NULL, CDS_FULLSCREEN, 0) == DISP_CHANGE_SUCCESSFUL)
  3697. {
  3698. return S_OK;
  3699. }
  3700. }
  3701. else
  3702. {
  3703. if ((*pfnChangeDisplaySettingsExA)(pDeviceName,
  3704. &dm, NULL, CDS_FULLSCREEN, 0) == DISP_CHANGE_SUCCESSFUL)
  3705. {
  3706. return S_OK;
  3707. }
  3708. }
  3709. if (NumReadyDevices == NumDevices)
  3710. {
  3711. InformDriverFreeAGP(pDevice);
  3712. }
  3713. }
  3714. return D3DERR_DRIVERINTERNALERROR;
  3715. }
  3716. /*****************************Private*Routine******************************\
  3717. * DdSetMode
  3718. *
  3719. * History:
  3720. * 29-Nov-1999 -by- Scott MacDonald [smac]
  3721. * Wrote it.
  3722. \**************************************************************************/
  3723. #undef DPF_MODNAME
  3724. #define DPF_MODNAME "DdSetMode"
  3725. DWORD
  3726. APIENTRY
  3727. DdSetMode(
  3728. PD3D8_SETMODEDATA pSetMode
  3729. )
  3730. {
  3731. UINT BPP;
  3732. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) pSetMode->hDD;
  3733. // smac: How should lost devices behave?
  3734. CheckForDeviceLost(pSetMode->hDD);
  3735. pSetMode->ddRVal = D3DERR_DRIVERINTERNALERROR;
  3736. switch (pSetMode->Format)
  3737. {
  3738. case D3DFMT_P8:
  3739. BPP = 8;
  3740. break;
  3741. case D3DFMT_R5G6B5:
  3742. case D3DFMT_X1R5G5B5:
  3743. BPP = 16;
  3744. break;
  3745. case D3DFMT_R8G8B8:
  3746. BPP = 24;
  3747. break;
  3748. case D3DFMT_A8R8G8B8:
  3749. case D3DFMT_X8R8G8B8:
  3750. BPP = 32;
  3751. break;
  3752. default:
  3753. return DDHAL_DRIVER_HANDLED;
  3754. }
  3755. pSetMode->ddRVal = D3D8SetMode(pDeviceHandle,
  3756. pDeviceHandle->szDeviceName,
  3757. pSetMode->dwWidth,
  3758. pSetMode->dwHeight,
  3759. BPP,
  3760. pSetMode->dwRefreshRate,
  3761. pSetMode->bRestore);
  3762. return DDHAL_DRIVER_HANDLED;
  3763. }
  3764. /*****************************Private*Routine******************************\
  3765. * DdGetScanLine
  3766. *
  3767. * History:
  3768. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  3769. * Wrote it.
  3770. \**************************************************************************/
  3771. #undef DPF_MODNAME
  3772. #define DPF_MODNAME "DdGetScanLine"
  3773. DWORD
  3774. APIENTRY
  3775. DdGetScanLine(
  3776. PD3D8_GETSCANLINEDATA pGetScanLine
  3777. )
  3778. {
  3779. DDHAL_GETSCANLINEDATA ScanData;
  3780. DWORD dwRet;
  3781. if (CheckForDeviceLost(pGetScanLine->hDD))
  3782. {
  3783. goto DeviceLost;
  3784. }
  3785. dwRet = OsThunkDdGetScanLine(DDHANDLE(pGetScanLine->hDD),
  3786. (PDD_GETSCANLINEDATA) &ScanData);
  3787. if (ScanData.ddRVal == DDERR_SURFACELOST)
  3788. {
  3789. goto DeviceLost;
  3790. }
  3791. pGetScanLine->dwScanLine = ScanData.dwScanLine;
  3792. if (ScanData.ddRVal == DDERR_VERTICALBLANKINPROGRESS)
  3793. {
  3794. pGetScanLine->bInVerticalBlank = TRUE;
  3795. ScanData.ddRVal = S_OK;
  3796. }
  3797. else
  3798. {
  3799. pGetScanLine->bInVerticalBlank = FALSE;
  3800. }
  3801. pGetScanLine->ddRVal = MapLegacyResult(ScanData.ddRVal);
  3802. return dwRet;
  3803. DeviceLost:
  3804. {
  3805. static int LostScanLine;
  3806. // When lost, we want to mix up the return values in case somebody
  3807. // calling us is waiting for these values to change
  3808. pGetScanLine->ddRVal = DD_OK;
  3809. if (LostScanLine == 0)
  3810. {
  3811. pGetScanLine->dwScanLine = 0;
  3812. pGetScanLine->bInVerticalBlank = TRUE;
  3813. }
  3814. else
  3815. {
  3816. pGetScanLine->dwScanLine = LostScanLine;
  3817. pGetScanLine->bInVerticalBlank = FALSE;
  3818. }
  3819. if ((LostScanLine += 10) > 100)
  3820. {
  3821. LostScanLine = 0;
  3822. }
  3823. }
  3824. return DDHAL_DRIVER_HANDLED;
  3825. }
  3826. /*****************************Private*Routine******************************\
  3827. * DdSetExclusiveMode
  3828. *
  3829. * History:
  3830. * 22-Apr-1998 -by- John Stephens [johnstep]
  3831. * Wrote it.
  3832. \**************************************************************************/
  3833. #undef DPF_MODNAME
  3834. #define DPF_MODNAME "DdSetExclusiveMode"
  3835. DWORD
  3836. APIENTRY
  3837. DdSetExclusiveMode(
  3838. PD3D8_SETEXCLUSIVEMODEDATA pSetExclusiveMode
  3839. )
  3840. {
  3841. DDHAL_SETEXCLUSIVEMODEDATA ExclusiveData;
  3842. DWORD dwRet;
  3843. // smac: How should lost devices behave?
  3844. CheckForDeviceLost(pSetExclusiveMode->hDD);
  3845. ZeroMemory(&ExclusiveData, sizeof(ExclusiveData));
  3846. ExclusiveData.dwEnterExcl = pSetExclusiveMode->dwEnterExcl;
  3847. dwRet = OsThunkDdSetExclusiveMode(
  3848. DDHANDLE(pSetExclusiveMode->hDD),
  3849. (PDD_SETEXCLUSIVEMODEDATA) &ExclusiveData);
  3850. pSetExclusiveMode->ddRVal = MapLegacyResult(ExclusiveData.ddRVal);
  3851. return dwRet;
  3852. }
  3853. /*****************************Private*Routine******************************\
  3854. * DdFlipToGDISurface
  3855. *
  3856. * History:
  3857. * 22-Apr-1998 -by- John Stephens [johnstep]
  3858. * Wrote it.
  3859. \**************************************************************************/
  3860. #undef DPF_MODNAME
  3861. #define DPF_MODNAME "DdFlipToGDISurface"
  3862. DWORD
  3863. APIENTRY
  3864. DdFlipToGDISurface(
  3865. PD3D8_FLIPTOGDISURFACEDATA pFlipToGDISurface
  3866. )
  3867. {
  3868. DDHAL_FLIPTOGDISURFACEDATA FlipData;
  3869. DWORD dwRet;
  3870. // smac: How should lost devices behave?
  3871. CheckForDeviceLost(pFlipToGDISurface->hDD);
  3872. FlipData.dwToGDI = pFlipToGDISurface->dwToGDI;
  3873. FlipData.dwReserved = 0;
  3874. FlipData.ddRVal = E_FAIL;
  3875. dwRet = OsThunkDdFlipToGDISurface(
  3876. DDHANDLE(pFlipToGDISurface->hDD),
  3877. (PDD_FLIPTOGDISURFACEDATA) &FlipData);
  3878. if (DDHAL_DRIVER_HANDLED == dwRet)
  3879. pFlipToGDISurface->ddRVal = FlipData.ddRVal;
  3880. pFlipToGDISurface->ddRVal = MapLegacyResult(pFlipToGDISurface->ddRVal);
  3881. return dwRet;
  3882. }
  3883. /*****************************Private*Routine******************************\
  3884. * DdGetAvailDriverMemory
  3885. *
  3886. * History:
  3887. * 16-Feb-1997 -by- J. Andrew Goossen [andrewgo]
  3888. * Wrote it.
  3889. \**************************************************************************/
  3890. #undef DPF_MODNAME
  3891. #define DPF_MODNAME "DdGetAvailDriverMemory"
  3892. DWORD
  3893. APIENTRY
  3894. DdGetAvailDriverMemory(
  3895. PD3D8_GETAVAILDRIVERMEMORYDATA pGetAvailDriverMemory
  3896. )
  3897. {
  3898. DDHAL_GETAVAILDRIVERMEMORYDATA MemoryData;
  3899. DWORD dwRet;
  3900. // smac: How should lost devices behave?
  3901. CheckForDeviceLost(pGetAvailDriverMemory->hDD);
  3902. pGetAvailDriverMemory->dwFree = 0;
  3903. // Convert the pool to something that the driver can understand
  3904. memset(&MemoryData, 0, sizeof(MemoryData));
  3905. switch (pGetAvailDriverMemory->Pool)
  3906. {
  3907. case D3DPOOL_LOCALVIDMEM:
  3908. MemoryData.DDSCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
  3909. break;
  3910. case D3DPOOL_DEFAULT:
  3911. MemoryData.DDSCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
  3912. break;
  3913. case D3DPOOL_NONLOCALVIDMEM:
  3914. MemoryData.DDSCaps.dwCaps |= DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
  3915. break;
  3916. default:
  3917. return DDHAL_DRIVER_HANDLED;
  3918. }
  3919. if (pGetAvailDriverMemory->dwUsage & D3DUSAGE_DEPTHSTENCIL)
  3920. {
  3921. MemoryData.DDSCaps.dwCaps |= DDSCAPS_ZBUFFER;
  3922. }
  3923. if (pGetAvailDriverMemory->dwUsage & D3DUSAGE_RENDERTARGET)
  3924. {
  3925. MemoryData.DDSCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
  3926. }
  3927. if (pGetAvailDriverMemory->dwUsage & D3DUSAGE_TEXTURE)
  3928. {
  3929. MemoryData.DDSCaps.dwCaps |= DDSCAPS_TEXTURE;
  3930. }
  3931. dwRet = OsThunkDdGetAvailDriverMemory(
  3932. DDHANDLE(pGetAvailDriverMemory->hDD),
  3933. (PDD_GETAVAILDRIVERMEMORYDATA) &MemoryData);
  3934. pGetAvailDriverMemory->dwFree = MemoryData.dwFree;
  3935. return dwRet;
  3936. }
  3937. /*****************************Private*Routine******************************\
  3938. * D3D8QueryDirectDrawObject
  3939. *
  3940. * History:
  3941. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  3942. * Wrote it.
  3943. \**************************************************************************/
  3944. #undef DPF_MODNAME
  3945. #define DPF_MODNAME "D3D8QueryDirectDrawObject"
  3946. BOOL
  3947. APIENTRY
  3948. D3D8QueryDirectDrawObject(
  3949. HANDLE hDD,
  3950. PD3D8_DRIVERCAPS pDriverCaps,
  3951. PD3D8_CALLBACKS pCallbacks,
  3952. char* pDeviceName,
  3953. HINSTANCE hLibrary,
  3954. D3D8_GLOBALDRIVERDATA* pGblDriverData,
  3955. D3DHAL_D3DEXTENDEDCAPS* pExtendedCaps,
  3956. LPDDSURFACEDESC pTextureFormats,
  3957. LPDDPIXELFORMAT pZStencilFormats,
  3958. UINT* pcTextureFormats,
  3959. UINT* pcZStencilFormats
  3960. )
  3961. {
  3962. PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
  3963. DD_HALINFO HalInfo;
  3964. DWORD adwCallBackFlags[3];
  3965. DWORD dwFlags;
  3966. VIDEOMEMORY* pVideoMemoryList;
  3967. VIDEOMEMORY* pVideoMemory;
  3968. DWORD dwNumHeaps;
  3969. DWORD dwNumFourCC;
  3970. D3DNTHAL_CALLBACKS D3dCallbacks;
  3971. D3DNTHAL_GLOBALDRIVERDATA D3dDriverData;
  3972. DD_D3DBUFCALLBACKS D3dBufferCallbacks;
  3973. DDSCAPSEX SurfCapsEx;
  3974. DD_GETDRIVERINFODATA GetDriverInfoData;
  3975. DWORD dwSize;
  3976. DD_MORESURFACECAPS * pSurfCaps;
  3977. DWORD dwRet;
  3978. DWORD i;
  3979. DD_MISCELLANEOUSCALLBACKS MiscCallbacks;
  3980. DD_MISCELLANEOUS2CALLBACKS Misc2Callbacks;
  3981. D3DNTHAL_CALLBACKS3 D3dCallbacks3;
  3982. D3DDISPLAYMODE Mode;
  3983. UINT MaxZStencilFormats;
  3984. UINT MaxTextureFormats;
  3985. DDASSERT(pcTextureFormats);
  3986. DDASSERT(pcZStencilFormats);
  3987. MaxTextureFormats = *pcTextureFormats;
  3988. MaxZStencilFormats = *pcZStencilFormats;
  3989. *pcTextureFormats=0;
  3990. *pcZStencilFormats=0;
  3991. // memset the extended caps and global driver data
  3992. ZeroMemory( pExtendedCaps, sizeof( *pExtendedCaps ) );
  3993. ZeroMemory( pGblDriverData, sizeof( *pGblDriverData ) );
  3994. // smac: How should lost devices behave?
  3995. CheckForDeviceLost(hDD);
  3996. // Get all of the neccesary caps
  3997. // Note: do this memset before the Query, since the caller might (ok will) be
  3998. // using a ptr internal to this struct to hold a reference to the
  3999. memset(pDriverCaps, 0, sizeof(D3D8_DRIVERCAPS));
  4000. // Behavior change: This code used to query for the supported texture format
  4001. // list if the device is not software only and the caller supplied a non-NULL
  4002. // buffer for the supported texture formats. Now, however, we never request
  4003. // texture formats at this point. We only request them if we need to, that
  4004. // is if the driver turns out to be a DirectX 7.0 driver or if it is a
  4005. // DirectX 8.0 driver that doesn't support the new format querying mechanism.
  4006. // This later clause is temporary only. Prior to RTM we will require
  4007. // DirectX 8.0 drivers to support the new format querying mechanism.
  4008. if (!OsThunkDdQueryDirectDrawObject(DDHANDLE(hDD),
  4009. &HalInfo,
  4010. &adwCallBackFlags[0],
  4011. &D3dCallbacks,
  4012. &D3dDriverData,
  4013. &D3dBufferCallbacks,
  4014. NULL,
  4015. &dwNumHeaps,
  4016. NULL,
  4017. &dwNumFourCC,
  4018. NULL))
  4019. {
  4020. return(FALSE);
  4021. }
  4022. if ((!(HalInfo.dwFlags & DDHALINFO_GETDRIVERINFO2)) &&
  4023. (!(IS_SOFTWARE_DRIVER(pDevice))) &&
  4024. (NULL != pTextureFormats))
  4025. {
  4026. // This is not a DirectX 8.0 or higher level driver so query again to get
  4027. // the texture formats (as we know we won't get them through the new DirectX 8.0
  4028. // interfaces).
  4029. if (!OsThunkDdQueryDirectDrawObject(DDHANDLE(hDD),
  4030. &HalInfo,
  4031. &adwCallBackFlags[0],
  4032. &D3dCallbacks,
  4033. &D3dDriverData,
  4034. &D3dBufferCallbacks,
  4035. pTextureFormats,
  4036. &dwNumHeaps,
  4037. NULL,
  4038. &dwNumFourCC,
  4039. NULL))
  4040. {
  4041. return(FALSE);
  4042. }
  4043. }
  4044. if (!IS_SOFTWARE_DRIVER(pDevice))
  4045. {
  4046. // Initialize the texture format count from the driver data.
  4047. // However, if this is a DX8 style driver this number will be
  4048. // replaced by a format count reported by the new DX8 mechanism
  4049. // code later in this function.
  4050. *pcTextureFormats = D3dDriverData.dwNumTextureFormats;
  4051. }
  4052. // Display drivers can all render windowed
  4053. if( (HalInfo.dwFlags & DDHALINFO_ISPRIMARYDISPLAY) ||
  4054. IsVGADevice(pDeviceName))
  4055. {
  4056. HalInfo.ddCaps.dwCaps2 |= DDCAPS2_CANRENDERWINDOWED;
  4057. }
  4058. pDriverCaps->D3DCaps.Caps = HalInfo.ddCaps.dwCaps;
  4059. pDriverCaps->D3DCaps.Caps2 = HalInfo.ddCaps.dwCaps2;
  4060. pDriverCaps->D3DCaps.Caps3 = HalInfo.ddCaps.dwSVCaps;
  4061. pDriverCaps->SVBCaps = HalInfo.ddCaps.dwSVBCaps;
  4062. pDriverCaps->VSBCaps = HalInfo.ddCaps.dwVSBCaps;
  4063. pDriverCaps->SVBCaps2 = HalInfo.ddCaps.dwSVBCaps2;
  4064. pDevice->DisplayPitch = HalInfo.vmiData.lDisplayPitch;
  4065. // Get the extended surface caps
  4066. SurfCapsEx.dwCaps2 = 0;
  4067. SurfCapsEx.dwCaps3 = 0;
  4068. SurfCapsEx.dwCaps4 = 0;
  4069. memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
  4070. GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
  4071. GetDriverInfoData.guidInfo = GUID_DDMoreSurfaceCaps;
  4072. dwSize = sizeof(DD_MORESURFACECAPS) + ((dwNumHeaps ? dwNumHeaps - 1 : 0) * sizeof(DDSCAPSEX) * 2);
  4073. pSurfCaps = (DD_MORESURFACECAPS*) MemAlloc(dwSize);
  4074. GetDriverInfoData.ddRVal = E_FAIL;
  4075. if (pSurfCaps != NULL)
  4076. {
  4077. pSurfCaps->dwSize = dwSize;
  4078. GetDriverInfoData.dwExpectedSize = dwSize;
  4079. GetDriverInfoData.lpvData = pSurfCaps;
  4080. dwRet = OsThunkDdGetDriverInfo(DDHANDLE(hDD), &GetDriverInfoData);
  4081. if ((dwRet == DDHAL_DRIVER_HANDLED) &&
  4082. (GetDriverInfoData.ddRVal == S_OK))
  4083. {
  4084. SurfCapsEx = pSurfCaps->ddsCapsMore;
  4085. }
  4086. MemFree(pSurfCaps);
  4087. }
  4088. // If the driver supports the "GetDriverInfo2" usage of GetDriverInfo then
  4089. // use that now to get the D3DCAPS8.
  4090. if ((HalInfo.dwFlags & DDHALINFO_GETDRIVERINFO2) &&
  4091. !IS_SOFTWARE_DRIVER(pDevice))
  4092. {
  4093. // This buffer is used to pass information down to the driver and get
  4094. // information back from the driver. The GetDriverInfo2 header and
  4095. // any additional information to pass to the driver is copied into this
  4096. // buffer prior to calling GetDriverInfo2. After the call the information
  4097. // returned by the driver is contained in this buffer. All information
  4098. // passed to and from the driver must fit within a buffer of this size.
  4099. DWORD buffer[MAX_GDI2_BUFFER_DWORD_SIZE];
  4100. DD_GETDRIVERINFO2DATA* pgdi2;
  4101. DD_GETFORMATCOUNTDATA* pgfcd;
  4102. DD_GETFORMATDATA* pgfd;
  4103. DD_DXVERSION* pDXVersion;
  4104. int i;
  4105. // Set up the DXVersion call
  4106. memset(&buffer, 0, sizeof(buffer));
  4107. pDXVersion = (DD_DXVERSION *)buffer;
  4108. // Before we do anything else, we notify the
  4109. // driver about the DX version information. We ignore
  4110. // errors here.
  4111. pDXVersion->gdi2.dwReserved = sizeof(DD_STEREOMODE);
  4112. pDXVersion->gdi2.dwMagic = D3DGDI2_MAGIC;
  4113. pDXVersion->gdi2.dwType = D3DGDI2_TYPE_DXVERSION;
  4114. pDXVersion->gdi2.dwExpectedSize = sizeof(DD_DXVERSION);
  4115. pDXVersion->dwDXVersion = DD_RUNTIME_VERSION;
  4116. memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
  4117. GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
  4118. GetDriverInfoData.guidInfo = GUID_GetDriverInfo2;
  4119. GetDriverInfoData.lpvData = &buffer;
  4120. GetDriverInfoData.dwExpectedSize = sizeof(DD_STEREOMODE);
  4121. dwRet = OsThunkDdGetDriverInfo(DDHANDLE(hDD), &GetDriverInfoData);
  4122. if (dwRet != DDHAL_DRIVER_HANDLED ||
  4123. GetDriverInfoData.ddRVal != S_OK)
  4124. {
  4125. // Errors are ignored here
  4126. dwRet = DDHAL_DRIVER_HANDLED;
  4127. }
  4128. memset(&buffer, 0, sizeof(buffer));
  4129. pgdi2 = (DD_GETDRIVERINFO2DATA*)&buffer;
  4130. // sizeof(DD_STEREOMODE)? The GUID for GetDriverInfo2 is shared with
  4131. // the stereo mode querying stuff. Therefore we need to pass down
  4132. // the structure size (and the expected data size) as
  4133. // sizeof(DD_STEREOMODE) even though we actually have a buffer (and
  4134. // expect a size of sizeof(D3DCAPS8).
  4135. pgdi2->dwReserved = sizeof(DD_STEREOMODE);
  4136. pgdi2->dwMagic = D3DGDI2_MAGIC;
  4137. pgdi2->dwType = D3DGDI2_TYPE_GETD3DCAPS8;
  4138. pgdi2->dwExpectedSize = sizeof(D3DCAPS8);
  4139. memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
  4140. GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
  4141. GetDriverInfoData.guidInfo = GUID_GetDriverInfo2;
  4142. GetDriverInfoData.lpvData = &buffer;
  4143. GetDriverInfoData.dwExpectedSize = sizeof(DD_STEREOMODE);
  4144. dwRet = OsThunkDdGetDriverInfo(DDHANDLE(hDD), &GetDriverInfoData);
  4145. if ((dwRet == DDHAL_DRIVER_HANDLED) && (GetDriverInfoData.ddRVal == S_OK))
  4146. {
  4147. // Looks like we got D3DCAPS8 back from the driver. Verify by means
  4148. // of the dwActualSize field in GetDriverInfoData.
  4149. if (sizeof(D3DCAPS8) != GetDriverInfoData.dwActualSize)
  4150. {
  4151. DPF(0, "Driver returned an data structure of incorrect size (!= sizeof(D3DCAPS8))");
  4152. return(FALSE);
  4153. }
  4154. // All went well. Copy the caps data across
  4155. memcpy(&pDriverCaps->D3DCaps, &buffer, sizeof(D3DCAPS8));
  4156. // Drivers may not set the ddraw caps correctly, or they might not update them
  4157. // across mode changes, so use the caps that we already have.
  4158. pDriverCaps->D3DCaps.Caps = HalInfo.ddCaps.dwCaps;
  4159. // Display drivers can all render windowed
  4160. if( (HalInfo.dwFlags & DDHALINFO_ISPRIMARYDISPLAY) ||
  4161. IsVGADevice(pDeviceName))
  4162. {
  4163. pDriverCaps->D3DCaps.Caps2 |= DDCAPS2_CANRENDERWINDOWED;
  4164. }
  4165. // Set the flag indicating that the DDI successfully reported DX8
  4166. // style caps
  4167. pDriverCaps->dwFlags |= DDIFLAG_D3DCAPS8;
  4168. // See device can do sub volume lock for volume texture.
  4169. if (pDriverCaps->D3DCaps.DevCaps & D3DDEVCAPS_SUBVOLUMELOCK)
  4170. {
  4171. pDevice->dwFlags |= DDDEVICE_SUPPORTSUBVOLUMELOCK;
  4172. }
  4173. }
  4174. // If this is a DX8 driver it needs to report it supported texture formats to us
  4175. // using GetDriverInfo2. This is done in two stages, one query to determine the
  4176. // number of supported formats, and one to actually retrieve those formats
  4177. // iteratively.
  4178. // Step 1: Get the number of supported formats
  4179. // Please see the description comments above for a description of why the
  4180. // reserved field is set to sizeof(DD_STEREOMODE)
  4181. memset(&buffer, 0, sizeof(buffer));
  4182. pgfcd = (DD_GETFORMATCOUNTDATA*)&buffer;
  4183. pgfcd->gdi2.dwReserved = sizeof(DD_STEREOMODE);
  4184. pgfcd->gdi2.dwMagic = D3DGDI2_MAGIC;
  4185. pgfcd->gdi2.dwType = D3DGDI2_TYPE_GETFORMATCOUNT;
  4186. pgfcd->gdi2.dwExpectedSize = sizeof(DD_GETFORMATCOUNTDATA);
  4187. #if DBG
  4188. // Ensure the driver actually sets the format count if it succeeds this call
  4189. pgfcd->dwFormatCount = BOGUS_FIELD_VALUE;
  4190. #endif // DBG
  4191. memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
  4192. GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
  4193. GetDriverInfoData.guidInfo = GUID_GetDriverInfo2;
  4194. GetDriverInfoData.lpvData = &buffer;
  4195. GetDriverInfoData.dwExpectedSize = sizeof(DD_STEREOMODE);
  4196. dwRet = OsThunkDdGetDriverInfo(DDHANDLE(hDD), &GetDriverInfoData);
  4197. if ((dwRet == DDHAL_DRIVER_HANDLED) && (GetDriverInfoData.ddRVal == S_OK))
  4198. {
  4199. // Looks like we got a DD_GETFORMATCOUNTDATA back from the driver. Verify by means
  4200. // of the dwActualSize field in GetDriverInfoData.
  4201. if (sizeof(DD_GETFORMATCOUNTDATA) != GetDriverInfoData.dwActualSize)
  4202. {
  4203. DPF(0, "Driver returned an data structure of incorrect size (!= sizeof(DD_GETFORMATCOUNTDATA))");
  4204. return(FALSE);
  4205. }
  4206. #ifdef DBG
  4207. if (BOGUS_FIELD_VALUE == ((DD_GETFORMATCOUNTDATA*)&buffer)->dwFormatCount)
  4208. {
  4209. DPF_ERR( "Driver succeeded GETFORMATCOUNT request but didn't set dwFormatCount. Driver error." );
  4210. return(FALSE);
  4211. }
  4212. #endif // DBG
  4213. // All went well. Replace the number of supported texture formats the driver
  4214. // reported to us with this new number. We don't use the legacy texture format
  4215. // list if this new mechanism is supported
  4216. *pcTextureFormats = ((DD_GETFORMATCOUNTDATA*)&buffer)->dwFormatCount;
  4217. // Step2: Query for each of the surface formats in turn.
  4218. // We only do this if the caller requested that we do by means of a non-NULL
  4219. // texture format buffer
  4220. if (NULL != pTextureFormats)
  4221. {
  4222. DWORD c;
  4223. DDSURFACEDESC* pOutFormat;
  4224. // For simplicities sake we ask for a single format at a time. Not exactly
  4225. // high-performance but this should not matter at this stage of the code.
  4226. pOutFormat = pTextureFormats;
  4227. *pcTextureFormats = min(MaxTextureFormats, *pcTextureFormats);
  4228. for (c = 0; c < (*pcTextureFormats); ++c)
  4229. {
  4230. // We reinitialize the entire request each time. We could probably
  4231. // optimize this but it doesn't seem worth it.
  4232. memset(&buffer, 0, sizeof(DD_GETFORMATDATA));
  4233. pgfd = (DD_GETFORMATDATA*)&buffer;
  4234. pgfd->gdi2.dwReserved = sizeof(DD_STEREOMODE);
  4235. pgfd->gdi2.dwMagic = D3DGDI2_MAGIC;
  4236. pgfd->gdi2.dwType = D3DGDI2_TYPE_GETFORMAT;
  4237. pgfd->gdi2.dwExpectedSize = sizeof(DD_GETFORMATDATA);
  4238. pgfd->dwFormatIndex = c;
  4239. #if DBG
  4240. // Ensure the driver actually sets the format count if it succeeds this call
  4241. pgfd->format.dwSize = BOGUS_FIELD_VALUE;
  4242. #endif // DBG
  4243. memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
  4244. GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
  4245. GetDriverInfoData.guidInfo = GUID_GetDriverInfo2;
  4246. GetDriverInfoData.lpvData = &buffer;
  4247. GetDriverInfoData.dwExpectedSize = sizeof(DD_STEREOMODE);
  4248. dwRet = OsThunkDdGetDriverInfo(DDHANDLE(hDD), &GetDriverInfoData);
  4249. if ((dwRet == DDHAL_DRIVER_HANDLED) && (GetDriverInfoData.ddRVal == S_OK))
  4250. {
  4251. // Looks like we got a DD_GETFORMATDATA back from the driver. Verify by means
  4252. // of the dwActualSize field in GetDriverInfoData.
  4253. if (sizeof(DD_GETFORMATDATA) != GetDriverInfoData.dwActualSize)
  4254. {
  4255. DPF(0, "Driver returned an data structure of incorrect size (!= sizeof(DD_GETFORMATDATA))");
  4256. return(FALSE);
  4257. }
  4258. DDASSERT(c == ((DD_GETFORMATDATA*)&buffer)->dwFormatIndex);
  4259. #ifdef DBG
  4260. if (BOGUS_FIELD_VALUE == (((DD_GETFORMATDATA*)&buffer)->format).dwSize)
  4261. {
  4262. DPF_ERR( "Driver succeeded GETFORMAT request but didn't set format. Driver error." );
  4263. return(FALSE);
  4264. }
  4265. #endif // DBG
  4266. // Looks like all went well. Initialize the surface description part of the format
  4267. // list and copy the pixel format we got from the driver across.
  4268. memset(pOutFormat, 0, sizeof(DDSURFACEDESC));
  4269. pOutFormat->dwSize = sizeof(DDSURFACEDESC);
  4270. pOutFormat->dwFlags = DDSD_PIXELFORMAT;
  4271. memcpy(&pOutFormat->ddpfPixelFormat, &(((DD_GETFORMATDATA*)&buffer)->format), sizeof(DDPIXELFORMAT));
  4272. ++pOutFormat;
  4273. }
  4274. }
  4275. }
  4276. }
  4277. else
  4278. {
  4279. DPF(0, "Driver claims DX8 but fails call to GETFORMATCOUNT" );
  4280. DPF(0, "DX7 texture format list will be used but this will change soon" );
  4281. DPF(0, "Fix driver to support DX8 style surface format reporting now" );
  4282. // This is a DirectX 8.0 level driver but it doesn't appear to support the
  4283. // new DirectX 8.0 style format querying mechanism so query the kernel
  4284. // again for the DirectX 7.0 style capabilities and use them instead.
  4285. // Note, this is a temporary measure only, prior to the RTM of DirectX 8.0
  4286. // this fallback will be removed and drivers will be required to support
  4287. // the new DirectX 8.0 style format reporting mechanism
  4288. if ((!IS_SOFTWARE_DRIVER(pDevice)) && (NULL != pTextureFormats))
  4289. {
  4290. if (!OsThunkDdQueryDirectDrawObject(DDHANDLE(hDD),
  4291. &HalInfo,
  4292. &adwCallBackFlags[0],
  4293. &D3dCallbacks,
  4294. &D3dDriverData,
  4295. &D3dBufferCallbacks,
  4296. pTextureFormats,
  4297. &dwNumHeaps,
  4298. NULL,
  4299. &dwNumFourCC,
  4300. NULL))
  4301. {
  4302. return(FALSE);
  4303. }
  4304. }
  4305. }
  4306. }
  4307. else if (D3dCallbacks.dwSize != 0 && D3dDriverData.dwSize != 0)
  4308. {
  4309. pGblDriverData->dwSize = D3dDriverData.dwSize;
  4310. //watcha gonna do:
  4311. DDASSERT(sizeof(pGblDriverData->hwCaps) == sizeof(D3dDriverData.hwCaps));
  4312. memcpy(&pGblDriverData->hwCaps, &D3dDriverData.hwCaps, sizeof(pGblDriverData->hwCaps));
  4313. pGblDriverData->dwNumVertices = D3dDriverData.dwNumVertices;
  4314. pGblDriverData->dwNumClipVertices = D3dDriverData.dwNumClipVertices;
  4315. // Get the D3D extended caps
  4316. GetDriverInfoData.guidInfo = GUID_D3DExtendedCaps;
  4317. GetDriverInfoData.ddRVal = E_FAIL;
  4318. GetDriverInfoData.dwExpectedSize = sizeof(D3DHAL_D3DEXTENDEDCAPS);
  4319. GetDriverInfoData.lpvData = pExtendedCaps;
  4320. dwRet = OsThunkDdGetDriverInfo(DDHANDLE(hDD), &GetDriverInfoData);
  4321. if ((dwRet != DDHAL_DRIVER_HANDLED) ||
  4322. (GetDriverInfoData.ddRVal != S_OK))
  4323. {
  4324. DPF_ERR( "Get EXTENDEDCAPS from the driver failed" );
  4325. return FALSE;
  4326. }
  4327. }
  4328. // Get the supported Z formats. We only do this if we are not using a
  4329. // software driver
  4330. if (!IS_SOFTWARE_DRIVER(pDevice))
  4331. {
  4332. DWORD tempbuf[249]; // make this <1K bytes or GetDriverInfo() fails cuz it cant do its "expected size overwrite" test within its own 1K tempbuffer
  4333. GetDriverInfoData.guidInfo = GUID_ZPixelFormats;
  4334. GetDriverInfoData.ddRVal = E_FAIL;
  4335. GetDriverInfoData.dwExpectedSize = sizeof(tempbuf);
  4336. GetDriverInfoData.lpvData = tempbuf;
  4337. dwRet = OsThunkDdGetDriverInfo(DDHANDLE(hDD), &GetDriverInfoData);
  4338. if ((dwRet != DDHAL_DRIVER_HANDLED) ||
  4339. (GetDriverInfoData.ddRVal != S_OK) ||
  4340. ((GetDriverInfoData.dwActualSize-sizeof(DWORD)) % sizeof(DDPIXELFORMAT) != 0) ||
  4341. ((tempbuf[0]*sizeof(DDPIXELFORMAT)+sizeof(DWORD))>sizeof(tempbuf)))
  4342. {
  4343. // It could be that this is an old driver that doesn't support
  4344. // stencil. We might be able to get some info from the global
  4345. // driver data.
  4346. if (pGblDriverData->hwCaps.dwDeviceZBufferBitDepth & DDBD_16)
  4347. {
  4348. (*pcZStencilFormats)++;
  4349. if (pZStencilFormats &&
  4350. (*pcZStencilFormats <= MaxZStencilFormats))
  4351. {
  4352. pZStencilFormats->dwSize = sizeof(DDPIXELFORMAT);
  4353. pZStencilFormats->dwFlags = DDPF_ZBUFFER;
  4354. pZStencilFormats->dwZBufferBitDepth = 16;
  4355. pZStencilFormats->dwStencilBitDepth = 0;
  4356. pZStencilFormats->dwZBitMask = 0xffff;
  4357. pZStencilFormats->dwStencilBitMask = 0x0000;
  4358. pZStencilFormats++;
  4359. }
  4360. }
  4361. if (pGblDriverData->hwCaps.dwDeviceZBufferBitDepth & DDBD_32)
  4362. {
  4363. (*pcZStencilFormats)++;
  4364. if (pZStencilFormats &&
  4365. (*pcZStencilFormats <= MaxZStencilFormats))
  4366. {
  4367. pZStencilFormats->dwSize = sizeof(DDPIXELFORMAT);
  4368. pZStencilFormats->dwFlags = DDPF_ZBUFFER;
  4369. pZStencilFormats->dwZBufferBitDepth = 32;
  4370. pZStencilFormats->dwStencilBitDepth = 0;
  4371. pZStencilFormats->dwZBitMask = 0xffffffff;
  4372. pZStencilFormats->dwStencilBitMask = 0x00000000;
  4373. pZStencilFormats++;
  4374. }
  4375. }
  4376. }
  4377. else
  4378. {
  4379. //We have a GetDriverInfo response to our Z format query. These are
  4380. //DDPIXELFORMATs that we can copy back to our caller
  4381. (*pcZStencilFormats) = tempbuf[0];
  4382. if(pZStencilFormats)
  4383. {
  4384. MaxZStencilFormats = min(MaxZStencilFormats, tempbuf[0]);
  4385. memcpy(pZStencilFormats, &tempbuf[1], MaxZStencilFormats * sizeof(DDPIXELFORMAT));
  4386. }
  4387. }
  4388. }
  4389. // Get info about the current mode
  4390. D3D8GetMode (NULL, pDeviceName, &Mode, 0);
  4391. pDevice->DisplayFormatWithAlpha = Mode.Format;
  4392. pDevice->DisplayFormatWithoutAlpha = Mode.Format;
  4393. if (Mode.Format == D3DFMT_X8R8G8B8)
  4394. {
  4395. if (HalInfo.vmiData.ddpfDisplay.dwFlags & DDPF_ALPHAPIXELS)
  4396. {
  4397. pDevice->DisplayFormatWithAlpha = D3DFMT_A8R8G8B8;
  4398. }
  4399. }
  4400. if (Mode.Format == D3DFMT_X1R5G5B5)
  4401. {
  4402. if (HalInfo.vmiData.ddpfDisplay.dwFlags & DDPF_ALPHAPIXELS)
  4403. {
  4404. pDevice->DisplayFormatWithAlpha = D3DFMT_A1R5G5B5;
  4405. }
  4406. }
  4407. pDriverCaps->DisplayWidth = Mode.Width;
  4408. pDriverCaps->DisplayHeight = Mode.Height;
  4409. pDriverCaps->DisplayFrequency = Mode.RefreshRate;
  4410. pDriverCaps->DisplayFormatWithoutAlpha = Mode.Format;
  4411. pDriverCaps->DisplayFormatWithAlpha = pDevice->DisplayFormatWithAlpha;
  4412. // Get the Miscellaneous callbacks
  4413. GetDriverInfoData.guidInfo = GUID_MiscellaneousCallbacks;
  4414. GetDriverInfoData.ddRVal = E_FAIL;
  4415. GetDriverInfoData.dwExpectedSize = sizeof(DD_MISCELLANEOUSCALLBACKS);
  4416. GetDriverInfoData.lpvData = &MiscCallbacks;
  4417. dwRet = OsThunkDdGetDriverInfo(DDHANDLE(hDD), &GetDriverInfoData);
  4418. if ((dwRet != DDHAL_DRIVER_HANDLED) ||
  4419. (GetDriverInfoData.ddRVal != S_OK))
  4420. {
  4421. memset (&MiscCallbacks, 0, sizeof(DD_MISCELLANEOUSCALLBACKS));
  4422. }
  4423. // Get the Miscellaneous2 callbacks
  4424. GetDriverInfoData.guidInfo = GUID_Miscellaneous2Callbacks;
  4425. GetDriverInfoData.ddRVal = E_FAIL;
  4426. GetDriverInfoData.dwExpectedSize = sizeof(DD_MISCELLANEOUS2CALLBACKS);
  4427. GetDriverInfoData.lpvData = &Misc2Callbacks;
  4428. dwRet = OsThunkDdGetDriverInfo(DDHANDLE(hDD), &GetDriverInfoData);
  4429. if ((dwRet != DDHAL_DRIVER_HANDLED) ||
  4430. (GetDriverInfoData.ddRVal != S_OK))
  4431. {
  4432. memset (&Misc2Callbacks, 0, sizeof(DD_MISCELLANEOUS2CALLBACKS));
  4433. }
  4434. // Get the D3Dcallbacks3 callbacks
  4435. GetDriverInfoData.guidInfo = GUID_D3DCallbacks3;
  4436. GetDriverInfoData.ddRVal = E_FAIL;
  4437. GetDriverInfoData.dwExpectedSize = sizeof(D3DNTHAL_CALLBACKS3);
  4438. GetDriverInfoData.lpvData = &D3dCallbacks3;
  4439. dwRet = OsThunkDdGetDriverInfo(DDHANDLE(hDD), &GetDriverInfoData);
  4440. if ((dwRet != DDHAL_DRIVER_HANDLED) ||
  4441. (GetDriverInfoData.ddRVal != S_OK))
  4442. {
  4443. memset (&D3dCallbacks3, 0, sizeof(D3DNTHAL_CALLBACKS3));
  4444. }
  4445. // Fill in the D3D8 Callback table
  4446. RtlZeroMemory(pCallbacks, sizeof(*pCallbacks));
  4447. pCallbacks->CreateSurface = DdCreateSurface;
  4448. pCallbacks->DestroySurface = DdDestroySurface;
  4449. pCallbacks->Lock = DdLock;
  4450. pCallbacks->Unlock = DdUnlock;
  4451. pCallbacks->Blt = DdBlt;
  4452. pCallbacks->GetScanLine = DdGetScanLine;
  4453. pCallbacks->Flip = DdFlip;
  4454. pCallbacks->WaitForVerticalBlank = DdWaitForVerticalBlank;
  4455. pCallbacks->GetBltStatus = DdGetBltStatus;
  4456. pCallbacks->GetFlipStatus = DdGetFlipStatus;
  4457. pCallbacks->SetMode = DdSetMode;
  4458. pCallbacks->FlipToGDISurface = DdFlipToGDISurface;
  4459. pCallbacks->SetExclusiveMode = DdSetExclusiveMode;
  4460. pCallbacks->GetAvailDriverMemory = DdGetAvailDriverMemory;
  4461. if (D3dCallbacks.ContextCreate != NULL)
  4462. {
  4463. pCallbacks->CreateContext = D3dContextCreate;
  4464. }
  4465. if (D3dCallbacks.ContextDestroy != NULL)
  4466. {
  4467. pCallbacks->ContextDestroy = D3dContextDestroy;
  4468. }
  4469. if (D3dCallbacks.ContextDestroyAll != NULL)
  4470. {
  4471. pCallbacks->ContextDestroyAll = D3dContextDestroyAll;
  4472. }
  4473. if (Misc2Callbacks.GetDriverState)
  4474. {
  4475. pCallbacks->GetDriverState = DdGetDriverState;
  4476. }
  4477. if (D3dCallbacks3.ValidateTextureStageState != NULL)
  4478. {
  4479. pCallbacks->ValidateTextureStageState = D3dValidateTextureStageState;
  4480. }
  4481. if (D3dCallbacks3.DrawPrimitives2 != NULL)
  4482. {
  4483. pCallbacks->DrawPrimitives2 = D3dDrawPrimitives2;
  4484. }
  4485. if (HalInfo.dwFlags & DDHALINFO_GETDRIVERINFO2)
  4486. {
  4487. pDevice->dwFlags |= DDDEVICE_GETDRIVERINFO2;
  4488. if (!(pDevice->dwFlags & DDDEVICE_INITIALIZED))
  4489. {
  4490. // Since this is the first time we have seen this device, we need
  4491. // to tell the driver that the runtime will send the propoer AGP
  4492. // notification.
  4493. InformDriverAGPWorkaroundAware((HANDLE) pDevice);
  4494. }
  4495. }
  4496. pDevice->dwFlags |= DDDEVICE_INITIALIZED;
  4497. if (FAILED(GetNTDeviceRect(pDeviceName,&pDevice->rcMonitor)))
  4498. {
  4499. SetRect(&pDevice->rcMonitor,0,0,
  4500. GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
  4501. }
  4502. // What about HW cursor support? check Must be done before SoftwareRast
  4503. // Caps Overrides
  4504. if (0 == pDriverCaps->D3DCaps.MaxStreams)
  4505. {
  4506. // The hardware driver is DX7
  4507. if (CanKnownDriverDoThis(pDevice, KNOWN_HWCURSOR))
  4508. {
  4509. pDriverCaps->D3DCaps.CursorCaps = D3DCURSORCAPS_COLOR;
  4510. pDriverCaps->KnownDriverFlags |= KNOWN_HWCURSOR;
  4511. if (CanKnownDriverDoThis(pDevice, KNOWN_HWCURSORLOWRES))
  4512. {
  4513. pDriverCaps->D3DCaps.CursorCaps |= D3DCURSORCAPS_LOWRES;
  4514. pDriverCaps->KnownDriverFlags |= KNOWN_HWCURSORLOWRES;
  4515. }
  4516. }
  4517. }
  4518. // need to save a HAL copy in thunklayer, for example DdBlt needs caps
  4519. pDevice->DDCaps = pDriverCaps->D3DCaps.Caps;
  4520. pDevice->SVBCaps = pDriverCaps->SVBCaps;
  4521. // If Refrast or the HEL has a hook, call it to let it change whatever it wants
  4522. if (IS_SOFTWARE_DRIVER(pDevice))
  4523. {
  4524. *pcZStencilFormats = 0;
  4525. SwDDIMungeCaps (
  4526. hLibrary,
  4527. hDD,
  4528. pDriverCaps,
  4529. pCallbacks,
  4530. pTextureFormats,
  4531. pcTextureFormats,
  4532. pDevice->pSwInitFunction
  4533. );
  4534. }
  4535. pDevice->DriverLevel = 0;
  4536. if (pDriverCaps->D3DCaps.MaxStreams != 0)
  4537. {
  4538. pDevice->DriverLevel = 8;
  4539. }
  4540. else if (pCallbacks->DrawPrimitives2 != NULL)
  4541. {
  4542. pDevice->DriverLevel = 7;
  4543. }
  4544. // Determine what version of windows is running so we can know
  4545. // what lock parameters to send. Whistler is version 5.1.
  4546. pDevice->bIsWhistler = IsWhistler();
  4547. // If it's a pre-dx8 driver and they support cubemaps, we need to
  4548. // specify whether they support mipped cubemaps or not.
  4549. if (pDevice->DriverLevel < 8)
  4550. {
  4551. if (CanKnownDriverDoThis(pDevice, KNOWN_MIPPEDCUBEMAPS))
  4552. {
  4553. pDriverCaps->KnownDriverFlags |= KNOWN_MIPPEDCUBEMAPS;
  4554. }
  4555. // Does this driver have a Z/Stencil depth restriction?
  4556. if (CanKnownDriverDoThis(pDevice, KNOWN_ZSTENCILDEPTH))
  4557. {
  4558. pDriverCaps->KnownDriverFlags |= KNOWN_ZSTENCILDEPTH;
  4559. }
  4560. // Does device have no driver known to over-queue windowed presentation blts?
  4561. if (CanKnownDriverDoThis(pDevice, KNOWN_NOTAWINDOWEDBLTQUEUER))
  4562. {
  4563. pDriverCaps->KnownDriverFlags |= KNOWN_NOTAWINDOWEDBLTQUEUER;
  4564. }
  4565. // Does device support D3DFMT_D16_LOCKABLE
  4566. if (CanKnownDriverDoThis(pDevice, KNOWN_D16_LOCKABLE))
  4567. {
  4568. pDriverCaps->KnownDriverFlags |= KNOWN_D16_LOCKABLE;
  4569. }
  4570. // Figure out what RT/Texture formats it supports
  4571. if (CanKnownDriverDoThis(pDevice, KNOWN_CANMISMATCHRT))
  4572. {
  4573. pDriverCaps->KnownDriverFlags |= KNOWN_CANMISMATCHRT;
  4574. }
  4575. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_X1R5G5B5))
  4576. {
  4577. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_X1R5G5B5;
  4578. }
  4579. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_R5G6B5))
  4580. {
  4581. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_R5G6B5;
  4582. }
  4583. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_X8R8G8B8))
  4584. {
  4585. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_X8R8G8B8;
  4586. }
  4587. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_A8R8G8B8))
  4588. {
  4589. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_A8R8G8B8;
  4590. }
  4591. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_A1R5G5B5))
  4592. {
  4593. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_A1R5G5B5;
  4594. }
  4595. if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_A4R4G4B4))
  4596. {
  4597. pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_A4R4G4B4;
  4598. }
  4599. }
  4600. if (NULL != HalInfo.lpD3DBufCallbacks )
  4601. {
  4602. pDevice->dwFlags |= DDDEVICE_SUPPORTD3DBUF;
  4603. }
  4604. else
  4605. {
  4606. pDevice->dwFlags &= ~DDDEVICE_SUPPORTD3DBUF;
  4607. }
  4608. return(TRUE);
  4609. }
  4610. //
  4611. // See NT bug 448720...
  4612. //
  4613. // AGP surfaces will be unlocked by the kernel mode in response to mode switches.
  4614. // App may still be writing to surface.
  4615. // Driver should therefore defer free of AGP memory until later.
  4616. // "Later" is defined as when the usermode determines the app is done writing and can tell
  4617. // the driver so.
  4618. //
  4619. // Drivers need to know that the runtime can do this so they can turn off any other workarounds
  4620. // they might have.
  4621. //
  4622. /*****************************Private*Routine******************************\
  4623. * GetDriverInfo2
  4624. *
  4625. * History:
  4626. * 06-Nov-2001 maxmcm Wrote it
  4627. \**************************************************************************/
  4628. #undef DPF_MODNAME
  4629. #define DPF_MODNAME "GetDriverInfo2"
  4630. DWORD
  4631. APIENTRY
  4632. GetDriverInfo2(
  4633. DWORD* pdwDrvRet,
  4634. HANDLE hDriver,
  4635. DWORD dwType,
  4636. DWORD dwSize,
  4637. void* pBuffer)
  4638. {
  4639. DD_GETDRIVERINFO2DATA* pGDI2Data;
  4640. DD_GETDRIVERINFODATA GetDriverInfoData;
  4641. DWORD dwRet;
  4642. PDDDEVICEHANDLE pDevice;
  4643. // In some cases (e.g. ProfileAdapter), it is possible that we can get
  4644. // here with a NULL device, so we should check for that.
  4645. pDevice = (PDDDEVICEHANDLE) hDriver;
  4646. if (pDevice == NULL)
  4647. {
  4648. *pdwDrvRet = E_FAIL;
  4649. return DDHAL_DRIVER_HANDLED;
  4650. }
  4651. // Don't call the driver if they don't support GETDRIVERINFO2
  4652. if (!(pDevice->dwFlags & DDDEVICE_GETDRIVERINFO2))
  4653. {
  4654. *pdwDrvRet = E_FAIL;
  4655. return DDHAL_DRIVER_HANDLED;
  4656. }
  4657. // Setup GetDriverInfo2 call
  4658. pGDI2Data = (DD_GETDRIVERINFO2DATA*) pBuffer;
  4659. memset(pGDI2Data, 0, sizeof(*pGDI2Data));
  4660. pGDI2Data->dwReserved = sizeof(DD_STEREOMODE);
  4661. pGDI2Data->dwMagic = D3DGDI2_MAGIC;
  4662. pGDI2Data->dwType = dwType;
  4663. pGDI2Data->dwExpectedSize = dwSize;
  4664. memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
  4665. GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
  4666. GetDriverInfoData.guidInfo = GUID_GetDriverInfo2;
  4667. GetDriverInfoData.lpvData = pGDI2Data;
  4668. GetDriverInfoData.dwExpectedSize = sizeof(DD_STEREOMODE);
  4669. // Ask the driver for information
  4670. dwRet = OsThunkDdGetDriverInfo(DDHANDLE(pDevice), &GetDriverInfoData);
  4671. *pdwDrvRet = GetDriverInfoData.ddRVal;
  4672. return dwRet;
  4673. }
  4674. void InformDriverAGPWorkaroundAware(HANDLE hDD)
  4675. {
  4676. DDNT_DEFERRED_AGP_AWARE_DATA aad;
  4677. DWORD dwDrvRet;
  4678. DWORD dwGDI2Ret;
  4679. dwGDI2Ret = GetDriverInfo2(&dwDrvRet, hDD,
  4680. _NT_D3DGDI2_TYPE_DEFERRED_AGP_AWARE,
  4681. sizeof(aad), &aad);
  4682. //drop the return code on the floor.... just a notification
  4683. }
  4684. void InformDriverFreeAGP(HANDLE hDD)
  4685. {
  4686. DDNT_FREE_DEFERRED_AGP_DATA fad;
  4687. DWORD dwDrvRet;
  4688. DWORD dwGDI2Ret;
  4689. fad.dwProcessId = GetCurrentProcessId();
  4690. dwGDI2Ret = GetDriverInfo2(&dwDrvRet, hDD,
  4691. _NT_D3DGDI2_TYPE_FREE_DEFERRED_AGP,
  4692. sizeof(fad), &fad);
  4693. //drop the return code on the floor.... just a notification
  4694. }
  4695. void InformDriverToDeferFrees(HANDLE hDD)
  4696. {
  4697. DDNT_FREE_DEFERRED_AGP_DATA fad;
  4698. DWORD dwDrvRet;
  4699. DWORD dwGDI2Ret;
  4700. fad.dwProcessId = GetCurrentProcessId();
  4701. dwGDI2Ret = GetDriverInfo2(&dwDrvRet, hDD,
  4702. _NT_D3DGDI2_TYPE_DEFER_AGP_FREES,
  4703. sizeof(fad), &fad);
  4704. //drop the return code on the floor.... just a notification
  4705. }
  4706. /*****************************Private*Routine******************************\
  4707. * D3D8CreateDirectDrawObject
  4708. *
  4709. * Calls GDI32 to get the global DirectDraw handle.
  4710. *
  4711. * History:
  4712. * 16-Nov-1999 -by- Scott MacDonald [smac]
  4713. * Wrote it.
  4714. \**************************************************************************/
  4715. #undef DPF_MODNAME
  4716. #define DPF_MODNAME "D3D8CreateDirectDrawObject"
  4717. VOID
  4718. APIENTRY
  4719. D3D8CreateDirectDrawObject(
  4720. HDC hdc,
  4721. char* szDeviceName,
  4722. HANDLE* phDD,
  4723. D3DDEVTYPE Type,
  4724. HINSTANCE* phLibrary,
  4725. VOID* pInitFunction
  4726. )
  4727. {
  4728. DDRAWI_DIRECTDRAW_GBL ddg;
  4729. PDDDEVICEHANDLE pDeviceHandle;
  4730. HKEY hKey = (HKEY) NULL;
  4731. *phDD = NULL;
  4732. ddg.hDD = 0;
  4733. pDeviceHandle = NULL;
  4734. DdCreateDirectDrawObject (&ddg, hdc);
  4735. if (ddg.hDD != 0)
  4736. {
  4737. pDeviceHandle = MemAlloc (sizeof(DDDEVICEHANDLE));
  4738. if (pDeviceHandle != NULL)
  4739. {
  4740. pDeviceHandle->hDD = (HANDLE)ddg.hDD;
  4741. *phDD = (HANDLE) pDeviceHandle;
  4742. lstrcpy (pDeviceHandle->szDeviceName, szDeviceName);
  4743. pDeviceHandle->DisplayUniqueness =
  4744. DdQueryDisplaySettingsUniqueness();
  4745. pDeviceHandle->hLastWnd = NULL;
  4746. pDeviceHandle->pClipList = NULL;
  4747. pDeviceHandle->pOrigClipList = NULL;
  4748. *phLibrary = NULL;
  4749. pDeviceHandle->DeviceType = Type;
  4750. if (Type == D3DDEVTYPE_REF)
  4751. {
  4752. *phLibrary = LoadLibrary (D3D8_REFRASTNAME);
  4753. pDeviceHandle->pDD = SwDDICreateDirectDraw();
  4754. if (pDeviceHandle->pDD == NULL)
  4755. {
  4756. *phDD = NULL;
  4757. }
  4758. else
  4759. {
  4760. pDeviceHandle->hLibrary = *phLibrary;
  4761. }
  4762. }
  4763. else if (Type == D3DDEVTYPE_SW)
  4764. {
  4765. pDeviceHandle->pDD = SwDDICreateDirectDraw();
  4766. if (pDeviceHandle->pDD == NULL)
  4767. {
  4768. *phDD = NULL;
  4769. }
  4770. else
  4771. {
  4772. pDeviceHandle->pSwInitFunction = pInitFunction;
  4773. }
  4774. }
  4775. }
  4776. }
  4777. if (*phDD == NULL)
  4778. {
  4779. if (pDeviceHandle)
  4780. {
  4781. MemFree (pDeviceHandle);
  4782. }
  4783. if (ddg.hDD != 0)
  4784. {
  4785. OsThunkDdDeleteDirectDrawObject((HANDLE) ddg.hDD);
  4786. }
  4787. }
  4788. else
  4789. {
  4790. // See if they want to explicitly enable/disable driver behavior
  4791. if (!RegOpenKey(HKEY_LOCAL_MACHINE, RESPATH_D3D, &hKey))
  4792. {
  4793. DWORD type;
  4794. DWORD value;
  4795. DWORD cb = sizeof(value);
  4796. pDeviceHandle->ForceFlagsOn = 0;
  4797. pDeviceHandle->ForceFlagsOff = 0;
  4798. #ifdef DEBUG
  4799. if (!RegQueryValueEx(hKey, "ForceDriverFlagsOn", NULL, &type, (CONST LPBYTE)&value, &cb))
  4800. {
  4801. pDeviceHandle->ForceFlagsOn = value;
  4802. }
  4803. cb = sizeof(value);
  4804. #endif
  4805. if (!RegQueryValueEx(hKey, "ForceDriverFlagsOff", NULL, &type, (CONST LPBYTE)&value, &cb))
  4806. {
  4807. pDeviceHandle->ForceFlagsOff = value;
  4808. }
  4809. RegCloseKey(hKey);
  4810. }
  4811. NumDevices++;
  4812. }
  4813. }
  4814. /*****************************Private*Routine******************************\
  4815. * D3D8DeleteDirectDrawObject
  4816. *
  4817. * Note that all associated surface objects must be deleted before the
  4818. * DirectDrawObject can be deleted.
  4819. *
  4820. * History:
  4821. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  4822. * Wrote it.
  4823. \**************************************************************************/
  4824. #undef DPF_MODNAME
  4825. #define DPF_MODNAME "D3D8DeleteDirectDrawObject"
  4826. VOID
  4827. APIENTRY
  4828. D3D8DeleteDirectDrawObject(
  4829. HANDLE hDD
  4830. )
  4831. {
  4832. PDDDEVICEHANDLE pHandle = (PDDDEVICEHANDLE) hDD;
  4833. PDEFERREDCREATE pTemp;
  4834. NumDevices--;
  4835. if (pHandle!= NULL)
  4836. {
  4837. PDEFERREDCREATE pDefCreate = pHandle->pDeferList;
  4838. OsThunkDdDeleteDirectDrawObject(DDHANDLE(hDD));
  4839. if (NULL != pHandle->SurfaceHandleList.dwList)
  4840. {
  4841. MemFree(pHandle->SurfaceHandleList.dwList);
  4842. }
  4843. if (NULL != pHandle->pDD)
  4844. {
  4845. if ( NULL != pHandle->pDD->lpGbl->lpDDCBtmp)
  4846. {
  4847. MemFree(pHandle->pDD->lpGbl->lpDDCBtmp);
  4848. }
  4849. MemFree(pHandle->pDD);
  4850. }
  4851. if (NULL != pHandle->pClipList)
  4852. {
  4853. MemFree(pHandle->pClipList);
  4854. }
  4855. if (NULL != pHandle->pOrigClipList)
  4856. {
  4857. MemFree(pHandle->pOrigClipList);
  4858. }
  4859. #ifdef DEBUG
  4860. // In debug print the types of objects
  4861. // that weren't released
  4862. if (pHandle->pSurfList != NULL)
  4863. {
  4864. PDDSURFHANDLE pSurf = pHandle->pSurfList;
  4865. DPF_ERR("Not all objects were freed: the following indicate "
  4866. "the types of unfreed objects.");
  4867. while (pSurf)
  4868. {
  4869. DebugPrintSurfaceInfo(pSurf);
  4870. pSurf = pSurf->pNext;
  4871. }
  4872. }
  4873. #endif
  4874. while (pDefCreate != NULL)
  4875. {
  4876. pTemp = pDefCreate->pNext;
  4877. MemFree(pDefCreate->CreateData.pSList);
  4878. MemFree(pDefCreate);
  4879. pDefCreate = pTemp;
  4880. }
  4881. DDASSERT(pHandle->pSurfList == NULL);
  4882. DDASSERT(pHandle->pContext == NULL);
  4883. MemFree(hDD);
  4884. }
  4885. }
  4886. /*****************************Private*Routine******************************\
  4887. * DdGetDC
  4888. *
  4889. * History:
  4890. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  4891. * Wrote it.
  4892. \**************************************************************************/
  4893. #undef DPF_MODNAME
  4894. #define DPF_MODNAME "D3D8GetDC"
  4895. HDC
  4896. APIENTRY
  4897. D3D8GetDC(
  4898. HANDLE hSurface,
  4899. LPPALETTEENTRY pPalette
  4900. )
  4901. {
  4902. if (CheckForDeviceLost((HANDLE)((PDDSURFHANDLE)hSurface)->pDevice))
  4903. {
  4904. return NULL;
  4905. }
  4906. return(OsThunkDdGetDC(GetSurfHandle(hSurface), pPalette));
  4907. }
  4908. /*****************************Private*Routine******************************\
  4909. * DdReleaseDC
  4910. *
  4911. * History:
  4912. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  4913. * Wrote it.
  4914. \**************************************************************************/
  4915. #undef DPF_MODNAME
  4916. #define DPF_MODNAME "D3D8ReleaseDC"
  4917. BOOL
  4918. APIENTRY
  4919. D3D8ReleaseDC(
  4920. HANDLE hSurface,
  4921. HDC hdc
  4922. )
  4923. {
  4924. DDASSERT(hdc != NULL);
  4925. return(OsThunkDdReleaseDC(GetSurfHandle(hSurface)));
  4926. }
  4927. /*****************************Private*Routine******************************\
  4928. * DdReenableDirectDrawObject
  4929. *
  4930. * History:
  4931. * 3-Dec-1995 -by- J. Andrew Goossen [andrewgo]
  4932. * Wrote it.
  4933. \**************************************************************************/
  4934. #undef DPF_MODNAME
  4935. #define DPF_MODNAME "D3D8ReenableDirectDrawObject"
  4936. BOOL
  4937. APIENTRY
  4938. D3D8ReenableDirectDrawObject(
  4939. HANDLE hDD,
  4940. BOOL* pbNewMode
  4941. )
  4942. {
  4943. BOOL bRet;
  4944. PDDDEVICEHANDLE pHandle = (PDDDEVICEHANDLE) hDD;
  4945. bRet = OsThunkDdReenableDirectDrawObject(DDHANDLE(hDD),
  4946. pbNewMode);
  4947. if (!bRet &&
  4948. ((pHandle->DeviceType == D3DDEVTYPE_REF) ||
  4949. (pHandle->DeviceType == D3DDEVTYPE_SW)) &&
  4950. !(pHandle->DDCaps & ~DDCAPS_NOHARDWARE))
  4951. {
  4952. bRet = TRUE;
  4953. }
  4954. return bRet;
  4955. }
  4956. /*****************************Private*Routine******************************\
  4957. * DdSetGammaRamp
  4958. *
  4959. * History:
  4960. * 18-Oct-1997 -by- smac
  4961. * Wrote it.
  4962. \**************************************************************************/
  4963. #undef DPF_MODNAME
  4964. #define DPF_MODNAME "D3D8SetGammaRamp"
  4965. BOOL
  4966. APIENTRY
  4967. D3D8SetGammaRamp(
  4968. HANDLE hDD,
  4969. HDC hdc,
  4970. LPVOID lpGammaRamp
  4971. )
  4972. {
  4973. if (CheckForDeviceLost(hDD))
  4974. {
  4975. return TRUE;
  4976. }
  4977. return(OsThunkDdSetGammaRamp(DDHANDLE(hDD), hdc,
  4978. lpGammaRamp));
  4979. }
  4980. /*****************************Private*Routine******************************\
  4981. * D3D8BuildModeTable
  4982. *
  4983. * History:
  4984. * 15-Dec-1999 -by- smac
  4985. * Wrote it.
  4986. \**************************************************************************/
  4987. #undef DPF_MODNAME
  4988. #define DPF_MODNAME "D3D8BuildModeTable"
  4989. VOID
  4990. APIENTRY
  4991. D3D8BuildModeTable(
  4992. char* pszDevice,
  4993. D3DDISPLAYMODE* pModeTable,
  4994. DWORD* pNumEntries,
  4995. D3DFORMAT Unknown16,
  4996. HANDLE hProfile,
  4997. BOOL b16bppSupported,
  4998. BOOL b32bppSupported
  4999. )
  5000. {
  5001. int i;
  5002. int j;
  5003. DEVMODE dm;
  5004. D3DFORMAT format;
  5005. int NumTempEntries = 0;
  5006. DWORD NumActualEntries = 0;
  5007. dm.dmSize = sizeof(dm);
  5008. for (i = 0; EnumDisplaySettings(pszDevice, i, &dm); ++i)
  5009. {
  5010. // Filter out all modes other than 15, 16 and 32bpp
  5011. if ((dm.dmBitsPerPel != 15) &&
  5012. (dm.dmBitsPerPel != 16) &&
  5013. (dm.dmBitsPerPel != 32))
  5014. {
  5015. continue;
  5016. }
  5017. if (((dm.dmBitsPerPel == 15) ||
  5018. (dm.dmBitsPerPel == 16)) &&
  5019. !b16bppSupported)
  5020. {
  5021. continue;
  5022. }
  5023. else if ((dm.dmBitsPerPel == 32) &&
  5024. !b32bppSupported)
  5025. {
  5026. continue;
  5027. }
  5028. // Make sure that we understand the format.
  5029. if ((dm.dmBitsPerPel == 16) ||
  5030. (dm.dmBitsPerPel == 15))
  5031. {
  5032. format = Unknown16;
  5033. }
  5034. else
  5035. {
  5036. DDASSERT(dm.dmBitsPerPel == 32);
  5037. format = D3DFMT_X8R8G8B8;
  5038. }
  5039. if (pModeTable != NULL)
  5040. {
  5041. ///The caller must pass us a number
  5042. DDASSERT( (*pNumEntries) );
  5043. if ( NumActualEntries >= (*pNumEntries) )
  5044. {
  5045. //we exceeded the number of entries allocated for us.
  5046. //tell the caller to re-query and try again.
  5047. NumActualEntries = 0;
  5048. break;
  5049. }
  5050. // Add the new mode.
  5051. pModeTable[NumActualEntries].Width = dm.dmPelsWidth;
  5052. pModeTable[NumActualEntries].Height = dm.dmPelsHeight;
  5053. pModeTable[NumActualEntries].RefreshRate = dm.dmDisplayFrequency;
  5054. pModeTable[NumActualEntries].Format = format;
  5055. }
  5056. NumActualEntries++;
  5057. }
  5058. //The caller will either pass a NULL modelist pointer, in which case
  5059. //it is expecting us to fill in the number of entries. If the modelist
  5060. // is non-null, the caller expects us to fill the table but not
  5061. // overwrite. If we find the table has grown, ask the caller to
  5062. // re-allocate by returning 0 modes.
  5063. (*pNumEntries) = NumActualEntries;
  5064. }
  5065. /*****************************Private*Routine******************************\
  5066. * D3D8IsDeviceLost
  5067. *
  5068. * History:
  5069. * 15-Dec-1999 -by- smac
  5070. * Wrote it.
  5071. \**************************************************************************/
  5072. #undef DPF_MODNAME
  5073. #define DPF_MODNAME "D3D8IsDeviceLost"
  5074. BOOL
  5075. APIENTRY
  5076. D3D8IsDeviceLost(
  5077. HANDLE hDD
  5078. )
  5079. {
  5080. return CheckForDeviceLost(hDD);
  5081. }
  5082. /*****************************Private*Routine******************************\
  5083. * D3D8CanRestoreNow
  5084. * 15-Dec-1999 -by- smac
  5085. * Wrote it.
  5086. \**************************************************************************/
  5087. #undef DPF_MODNAME
  5088. #define DPF_MODNAME "D3D8CanRestoreNow"
  5089. BOOL
  5090. APIENTRY
  5091. D3D8CanRestoreNow(
  5092. HANDLE hDD
  5093. )
  5094. {
  5095. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  5096. BOOL bNewMode;
  5097. D3D8_DRIVERCAPS DriverData;
  5098. D3D8_GLOBALDRIVERDATA D3DGlobalDriverData;
  5099. D3DHAL_D3DEXTENDEDCAPS D3DExtendedCaps;
  5100. D3D8_CALLBACKS Callbacks;
  5101. UINT uiDummy;
  5102. // If we aren't lost, then it's an easy call
  5103. if (!CheckForDeviceLost(hDD))
  5104. {
  5105. return TRUE;
  5106. }
  5107. // Otherwise, we actually need to call the kernel and look at the caps
  5108. memset(&DriverData, 0, sizeof(DriverData));
  5109. memset(&D3DGlobalDriverData, 0, sizeof(D3DGlobalDriverData));
  5110. memset(&D3DExtendedCaps, 0, sizeof(D3DExtendedCaps));
  5111. memset(&Callbacks, 0, sizeof(Callbacks));
  5112. if (!D3D8ReenableDirectDrawObject (hDD,&bNewMode) ||
  5113. !D3D8QueryDirectDrawObject(hDD,
  5114. &DriverData,
  5115. &Callbacks,
  5116. pDeviceHandle->szDeviceName,
  5117. pDeviceHandle->hLibrary,
  5118. &D3DGlobalDriverData,
  5119. &D3DExtendedCaps,
  5120. NULL,NULL,&uiDummy,&uiDummy))
  5121. {
  5122. return FALSE;
  5123. }
  5124. if (IS_SOFTWARE_DRIVER(hDD) ||
  5125. ((DriverData.D3DCaps.Caps & DDCAPS_3D) &&
  5126. (Callbacks.DrawPrimitives2 != NULL)))
  5127. {
  5128. return TRUE;
  5129. }
  5130. return FALSE;
  5131. }
  5132. /*****************************Private*Routine******************************\
  5133. * D3D8RestoreDevice
  5134. * 15-Dec-1999 -by- smac
  5135. * Wrote it.
  5136. \**************************************************************************/
  5137. #undef DPF_MODNAME
  5138. #define DPF_MODNAME "D3D8RestoreDevice"
  5139. void
  5140. APIENTRY
  5141. D3D8RestoreDevice (
  5142. HANDLE hDD
  5143. )
  5144. {
  5145. HRESULT hr;
  5146. DWORD i, j, k;
  5147. DWORD Width, Height, Depth;
  5148. BYTE *SliceSrc, *SliceDst, *RowSrc, *RowDst;
  5149. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  5150. PDDSURFHANDLE pSurf;
  5151. PD3DCONTEXTHANDLE pContext = pDeviceHandle->pContext;
  5152. PDEFERREDCREATE pDefCreate = pDeviceHandle->pDeferList;
  5153. PDEFERREDCREATE *ppNext = &pDeviceHandle->pDeferList;
  5154. PDEFERREDCREATE pTemp;
  5155. D3D8_LOCKDATA LockData;
  5156. D3D8_UNLOCKDATA UnlockData;
  5157. ULONG_PTR pVidmem[32 * 6];
  5158. // First, say that we aren't lost anymore
  5159. pDeviceHandle->DisplayUniqueness =
  5160. DdQueryDisplaySettingsUniqueness();
  5161. pDeviceHandle->bDeviceLost = FALSE;
  5162. pDeviceHandle->dwFlags &= ~DDDEVICE_DP2ERROR;
  5163. // Now, check for any sysmem surfaces that were created while
  5164. // the device was lost and call CreateSurfaceEx if they need it.
  5165. pSurf = pDeviceHandle->pSurfList;
  5166. while (pSurf != NULL)
  5167. {
  5168. if ((pSurf->dwCookie != 0) &&
  5169. (pSurf->dwFlags & DDSURF_DEFERCREATEEX))
  5170. {
  5171. hr = OsThunkDdCreateSurfaceEx(
  5172. DDHANDLE(hDD),
  5173. pSurf->hSurface,
  5174. pSurf->dwCookie);
  5175. if (SUCCEEDED(hr))
  5176. {
  5177. pSurf->dwFlags &= ~DDSURF_DEFERCREATEEX;
  5178. }
  5179. else
  5180. {
  5181. // TODO: Handle error condition
  5182. DPF(0, "CreateSurfaceEx failed when resurrecting sysmem or D3D managed surfaces");
  5183. }
  5184. }
  5185. pSurf = pSurf->pNext;
  5186. }
  5187. // Now, create the D3D context if we need to.
  5188. if ((pContext != NULL) &&
  5189. (pContext->dwFlags & D3DCONTEXT_DEFERCREATE))
  5190. {
  5191. D3D8_CONTEXTCREATEDATA ContextData;
  5192. memset(&ContextData, 0, sizeof(ContextData));
  5193. ContextData.hDD = DDHANDLE(hDD);
  5194. ContextData.dwPID = pContext->dwPID;
  5195. ContextData.dwhContext = (ULONG_PTR) pContext->hDeferHandle;
  5196. OsThunkD3dContextCreate(DDHANDLE(hDD),
  5197. GetSurfHandle(pContext->pSurface),
  5198. GetSurfHandle(pContext->pDDSZ),
  5199. (D3DNTHAL_CONTEXTCREATEI *)&ContextData);
  5200. if (SUCCEEDED(ContextData.ddrval))
  5201. {
  5202. pContext->dwhContext = (HANDLE) ContextData.dwhContext;
  5203. pContext->dwFlags &= ~D3DCONTEXT_DEFERCREATE;
  5204. }
  5205. else
  5206. {
  5207. // TODO: Handle error condition
  5208. }
  5209. }
  5210. // Finally resurrect our deferred driver managed surfaces (Gulp!)
  5211. while (pDefCreate != NULL)
  5212. {
  5213. DDASSERT(pDefCreate->CreateData.dwSCnt <= 32 * 6);
  5214. // First check if the deferred surface exists at all. The problem
  5215. // is that DdDestroySurface could have been called. We could have
  5216. // removed the surface from the deferred list in DdDestroySurface
  5217. // but since DdDestroySurface is called piecemeal, it gets
  5218. // very annoying. The removal is best done here.
  5219. // ASSUMPTION: if pSList[0].hKernelHandle is NULL then
  5220. // pSList[1,2,etc].hKernelHandle are also NULL. There is no
  5221. // reason for this to be not the case as of 3/2001.
  5222. if (pDefCreate->CreateData.pSList[0].hKernelHandle == NULL)
  5223. {
  5224. pTemp = pDefCreate->pNext;
  5225. *ppNext = pTemp;
  5226. MemFree(pDefCreate->CreateData.pSList);
  5227. MemFree(pDefCreate);
  5228. pDefCreate = pTemp;
  5229. continue;
  5230. }
  5231. // Save off all the fpVidmems since they will be overwritten
  5232. for (i = 0; i < pDefCreate->CreateData.dwSCnt; i++)
  5233. {
  5234. pSurf = (PDDSURFHANDLE) pDefCreate->CreateData.pSList[i].hKernelHandle;
  5235. pVidmem[i] = pSurf->fpVidMem;
  5236. }
  5237. // Attempt to resurrect
  5238. pDefCreate->CreateData.bReUse = TRUE;
  5239. hr = DdCreateSurface(&pDefCreate->CreateData);
  5240. if (SUCCEEDED(hr))
  5241. {
  5242. for (i = 0; i < pDefCreate->CreateData.dwSCnt; i++)
  5243. {
  5244. pSurf = (PDDSURFHANDLE) pDefCreate->CreateData.pSList[i].hKernelHandle;
  5245. // Reset DDSURF_SYSMEMALLOCATED to keep DdLock below happy
  5246. pSurf->dwFlags &= ~DDSURF_SYSMEMALLOCATED;
  5247. // Lock and copy
  5248. ZeroMemory(&LockData, sizeof(LockData));
  5249. LockData.hDD = hDD;
  5250. LockData.hSurface = pSurf;
  5251. hr = DdLock(&LockData);
  5252. if (SUCCEEDED(hr))
  5253. {
  5254. SliceSrc = (BYTE*)pVidmem[i];
  5255. SliceDst = (BYTE*)LockData.lpSurfData;
  5256. Width = pDefCreate->CreateData.pSList[i].cpWidth;
  5257. Height = pDefCreate->CreateData.pSList[i].cpHeight;
  5258. Depth = pDefCreate->CreateData.pSList[i].cpDepth;
  5259. if (!(pDefCreate->CreateData.Type == D3DRTYPE_VOLUME ||
  5260. pDefCreate->CreateData.Type == D3DRTYPE_VOLUMETEXTURE))
  5261. {
  5262. Depth = 1;
  5263. }
  5264. for (j = 0; j < Depth; ++j)
  5265. {
  5266. RowSrc = SliceSrc;
  5267. RowDst = SliceDst;
  5268. for (k = 0; k < Height; ++k)
  5269. {
  5270. CopyMemory(RowDst, RowSrc, min(LockData.lPitch, (LONG)Width * 8));
  5271. RowSrc += Width * 8;
  5272. RowDst += LockData.lPitch;
  5273. }
  5274. SliceSrc += Width * Height * 8;
  5275. SliceDst += LockData.lSlicePitch;
  5276. }
  5277. ZeroMemory(&UnlockData, sizeof(UnlockData));
  5278. UnlockData.hDD = hDD;
  5279. UnlockData.hSurface = pSurf;
  5280. hr = DdUnlock(&UnlockData);
  5281. if (FAILED(hr))
  5282. {
  5283. // TODO: Handle/(ignore?) failure
  5284. DPF(0,"Unlock failed when resurrecting driver managed surface.");
  5285. }
  5286. }
  5287. else
  5288. {
  5289. // TODO: Handle/(ignore?) failure
  5290. DPF(0,"Lock failed when resurrecting driver managed surface. Texture may go missing.");
  5291. }
  5292. // Free the temporary fpVidmem that we allocated in CreateVidmemSurface
  5293. MemFree((VOID*)pVidmem[i]);
  5294. }
  5295. // Remove from list and freeup all memory
  5296. pTemp = pDefCreate->pNext;
  5297. *ppNext = pTemp;
  5298. MemFree(pDefCreate->CreateData.pSList);
  5299. MemFree(pDefCreate);
  5300. pDefCreate = pTemp;
  5301. }
  5302. else
  5303. {
  5304. // We set ReUse to FALSE to indicate that we were not able to resurrect
  5305. pDefCreate->CreateData.bReUse = FALSE;
  5306. ppNext = &(pDefCreate->pNext);
  5307. pDefCreate = pDefCreate->pNext;
  5308. }
  5309. }
  5310. if (pDeviceHandle->pDeferList != NULL)
  5311. {
  5312. // TODO:
  5313. // Ummm, we were not able to resurrect. This may be due to out of memory
  5314. // or if a mode switch happened as we were trying to Reset (ACK!). The
  5315. // former probably needs to be reported to the app. The latter is
  5316. // probably harmless, because the app will eventually realize this and
  5317. // try again.
  5318. DPF(0,"Unable to resurrect all driver managed surfaces.");
  5319. }
  5320. }
  5321. /*****************************Private*Routine******************************\
  5322. * D3D8AreVidmemSurfaces
  5323. * 15-Dec-1999 -by- smac
  5324. * Wrote it.
  5325. \**************************************************************************/
  5326. #undef DPF_MODNAME
  5327. #define DPF_MODNAME "D3D8DoVidmemSurfacesExist "
  5328. BOOL
  5329. APIENTRY
  5330. D3D8DoVidmemSurfacesExist (
  5331. HANDLE hDD
  5332. )
  5333. {
  5334. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  5335. PDDSURFHANDLE pSurf;
  5336. // Walk the list and return TRUE is we find any surfaces that are either
  5337. // local or nonlocal vidmem.
  5338. pSurf = pDeviceHandle->pSurfList;
  5339. while (pSurf != NULL)
  5340. {
  5341. if ((pSurf->Pool == D3DPOOL_LOCALVIDMEM) ||
  5342. (pSurf->Pool == D3DPOOL_NONLOCALVIDMEM) ||
  5343. (pSurf->dwFlags & DDSURF_TREATASVIDMEM))
  5344. {
  5345. #if DBG
  5346. DPF(0,"The following D3DPOOL_DEFAULT surfaces/buffers/textures still exist");
  5347. pSurf = pDeviceHandle->pSurfList;
  5348. while (pSurf != NULL)
  5349. {
  5350. if ((pSurf->Pool == D3DPOOL_LOCALVIDMEM) ||
  5351. (pSurf->Pool == D3DPOOL_NONLOCALVIDMEM) ||
  5352. (pSurf->dwFlags & DDSURF_TREATASVIDMEM))
  5353. {
  5354. DebugPrintSurfaceInfo(pSurf);
  5355. }
  5356. pSurf = pSurf->pNext;
  5357. }
  5358. #endif
  5359. return TRUE;
  5360. }
  5361. pSurf = pSurf->pNext;
  5362. }
  5363. // Is this the first time that the device has become ready?
  5364. if (!(pDeviceHandle->dwFlags & DDDEVICE_READY) &&
  5365. (pDeviceHandle->bDeviceLost))
  5366. {
  5367. pDeviceHandle->dwFlags |= DDDEVICE_READY;
  5368. if (++NumReadyDevices == NumDevices)
  5369. {
  5370. InformDriverFreeAGP(pDeviceHandle);
  5371. }
  5372. }
  5373. return FALSE;
  5374. }
  5375. #undef DPF_MODNAME
  5376. #define DPF_MODNAME "D3D8BeginProfile"
  5377. HANDLE
  5378. APIENTRY
  5379. D3D8BeginProfile(
  5380. char* pDeviceName)
  5381. {
  5382. return NULL;
  5383. }
  5384. #undef DPF_MODNAME
  5385. #define DPF_MODNAME "D3D8EndProfile"
  5386. void
  5387. APIENTRY
  5388. D3D8EndProfile(
  5389. HANDLE Handle)
  5390. {
  5391. }
  5392. DWORD APIENTRY D3D8SetCooperativeLevel(
  5393. HANDLE hDD,
  5394. HWND hWnd,
  5395. DWORD dwFlags )
  5396. {
  5397. return S_OK;
  5398. }
  5399. BOOL APIENTRY D3D8IsDummySurface(
  5400. HANDLE hSurface )
  5401. {
  5402. return FALSE;
  5403. }
  5404. VOID APIENTRY D3D8LoseDevice(
  5405. HANDLE hDD )
  5406. {
  5407. PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
  5408. PDDSURFHANDLE pSurf;
  5409. if (!pDeviceHandle->bDeviceLost)
  5410. {
  5411. pDeviceHandle->bDeviceLost = TRUE;
  5412. pSurf = pDeviceHandle->pSurfList;
  5413. while (pSurf != NULL)
  5414. {
  5415. if (IS_SURFACE_LOOSABLE(pSurf))
  5416. {
  5417. FreeSurfaceObject(pSurf);
  5418. pSurf->fpVidMem = (ULONG_PTR) NULL;
  5419. }
  5420. pSurf = pSurf->pNext;
  5421. }
  5422. }
  5423. }