--- /dev/null
+#define STDCALL __stdcall
+#include <d3d9.h>
+#include <ddraw.h>
+#include <d3dnthal.h>
+#include <d3dhal.h>
+#include <ddrawi.h>
+#include <ddrawgdi.h>
+#include <dll/directx/d3d8thk.h>
+#include <debug.h>
+#include <strsafe.h>
+#include <limits.h>
+#include "d3d9_helpers.h"
+#include "d3d9_caps.h"
+#include "adapter.h"
+
+static INT g_NumDevices = 0;
+
+void CreateDisplayModeList(LPCSTR lpszDeviceName, D3DDISPLAYMODE* pDisplayModes, DWORD* pNumDisplayModes, D3DFORMAT Default16BitFormat, D3D9_Unknown6BC_INT* pUnknown6BC)
+{
+ DEVMODEA DevMode;
+ DWORD ModeIndex = 0;
+ DWORD ValidModes = 0;
+
+ while (TRUE == EnumDisplaySettingsA(lpszDeviceName, ModeIndex, &DevMode))
+ {
+ D3DFORMAT DefaultFormat;
+
+ if (DevMode.dmBitsPerPel != 15 &&
+ DevMode.dmBitsPerPel != 16 &&
+ DevMode.dmBitsPerPel != 32)
+ {
+ ++ModeIndex;
+ continue;
+ }
+
+ ++ValidModes;
+
+ if (DevMode.dmBitsPerPel == 15 || DevMode.dmBitsPerPel == 16)
+ {
+ if (NULL == pUnknown6BC)
+ {
+ ++ModeIndex;
+ continue;
+ }
+
+ DefaultFormat = Default16BitFormat;
+ }
+ else
+ {
+ DefaultFormat = D3DFMT_X8R8G8B8;
+ }
+
+ if (NULL != pDisplayModes)
+ {
+ if (ValidModes == *pNumDisplayModes)
+ break;
+
+ pDisplayModes->Width = DevMode.dmPelsWidth;
+ pDisplayModes->Height = DevMode.dmPelsHeight;
+ pDisplayModes->RefreshRate = DevMode.dmDisplayFrequency;
+ pDisplayModes->Format = DefaultFormat;
+ ++pDisplayModes;
+ }
+
+ ++ModeIndex;
+ }
+
+ *pNumDisplayModes = ValidModes;
+}
+
+static void CreateInternalDeviceData(HDC hDC, LPCSTR lpszDeviceName, D3D9_Unknown6BC_INT** ppUnknown, D3DDEVTYPE DeviceType, HMODULE* hD3DRefDll)
+{
+ D3D9_Unknown6BC_INT* pUnknown6BC;
+ DWORD ValueSize;
+
+ if (ppUnknown) *ppUnknown = NULL;
+ if (hD3DRefDll) *hD3DRefDll = NULL;
+
+ if (DeviceType != D3DDEVTYPE_HAL)
+ {
+ /* TODO: Implement D3DDEVTYPE_REF and D3DDEVTYPE_SW */
+ UNIMPLEMENTED;
+ return;
+ }
+
+ pUnknown6BC = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3D9_Unknown6BC_INT));
+ if (NULL == pUnknown6BC)
+ {
+ DPRINT1("Out of memory");
+ return;
+ }
+
+ pUnknown6BC->hDD = OsThunkDdCreateDirectDrawObject(hDC);
+ if (0 == pUnknown6BC->hDD)
+ {
+ HeapFree(GetProcessHeap(), 0, pUnknown6BC);
+ return;
+ }
+
+
+ StringCbCopyA(pUnknown6BC->szDeviceName, CCHDEVICENAME, lpszDeviceName);
+ //pUnknown6BC->DeviceUniq = DdQueryDisplaySettingsUniqueness();
+ pUnknown6BC->DeviceType = DeviceType;
+
+
+ ValueSize = sizeof(DWORD);
+ ReadRegistryValue(REG_DWORD, "ForceDriverFlagsOn", (LPBYTE)&pUnknown6BC->bForceDriverFlagsOn, &ValueSize);
+
+ ValueSize = sizeof(DWORD);
+ ReadRegistryValue(REG_DWORD, "ForceDriverFlagsOff", (LPBYTE)&pUnknown6BC->bForceDriverFlagsOff, &ValueSize);
+
+ ++g_NumDevices;
+
+ *ppUnknown = pUnknown6BC;
+}
+
+static void ReleaseInternalDeviceData(LPD3D9_DEVICEDATA pDeviceData)
+{
+ OsThunkDdDeleteDirectDrawObject(pDeviceData->pUnknown6BC->hDD);
+
+ HeapFree(GetProcessHeap(), 0, pDeviceData->pUnknown6BC);
+ pDeviceData->pUnknown6BC = NULL;
+
+ --g_NumDevices;
+}
+
+BOOL GetDeviceData(LPD3D9_DEVICEDATA pDeviceData)
+{
+ BOOL bRet;
+ D3DHAL_GLOBALDRIVERDATA GlobalDriverData;
+ D3DHAL_D3DEXTENDEDCAPS D3dExtendedCaps;
+ LPDDSURFACEDESC puD3dTextureFormats;
+ DDPIXELFORMAT* pD3dZStencilFormatList;
+ D3DDISPLAYMODE* pD3dDisplayModeList;
+ D3DQUERYTYPE* pD3dQueryList;
+ DWORD NumTextureFormats = 0;
+ DWORD NumStencilFormats = 0;
+ DWORD NumExtendedFormats = 0;
+ DWORD NumQueries = 0;
+
+ if (NULL == pDeviceData->pUnknown6BC)
+ {
+ CreateInternalDeviceData(
+ pDeviceData->hDC,
+ pDeviceData->szDeviceName,
+ &pDeviceData->pUnknown6BC,
+ pDeviceData->DeviceType,
+ &pDeviceData->hD3DRefDll
+ );
+
+ if (NULL == pDeviceData->pUnknown6BC)
+ {
+ DPRINT1("Failed to create DirectDrawObject for Direct3D9");
+ return FALSE;
+ }
+ }
+ else
+ {
+ D3D9_DRIVERCAPS DriverCaps;
+ D3D9_UnknownA8h_INT unknownA8h;
+
+ if (FALSE == CanReenableDirectDrawObject(pDeviceData->pUnknown6BC))
+ {
+ DPRINT1("Failed to re-enable DirectDrawObject");
+ return FALSE;
+ }
+
+ bRet = GetD3D9DriverInfo(
+ pDeviceData->pUnknown6BC,
+ &DriverCaps,
+ &unknownA8h,
+ pDeviceData->szDeviceName,
+ pDeviceData->hD3DRefDll,
+ &GlobalDriverData,
+ &D3dExtendedCaps,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &NumTextureFormats,
+ &NumStencilFormats,
+ &NumExtendedFormats,
+ &NumQueries
+ );
+
+ if (TRUE == bRet)
+ {
+ pDeviceData->DriverCaps.dwDisplayWidth = DriverCaps.dwDisplayWidth;
+ pDeviceData->DriverCaps.dwDisplayHeight = DriverCaps.dwDisplayHeight;
+ pDeviceData->DriverCaps.RawDisplayFormat = DriverCaps.RawDisplayFormat;
+ pDeviceData->DriverCaps.DisplayFormat = DriverCaps.DisplayFormat;
+ pDeviceData->DriverCaps.dwRefreshRate = DriverCaps.dwRefreshRate;
+ }
+
+ return bRet;
+ }
+
+ /* Cleanup of old stuff */
+ if (pDeviceData->DriverCaps.pSupportedFormatOps)
+ {
+ HeapFree(GetProcessHeap(), 0, pDeviceData->DriverCaps.pSupportedFormatOps);
+ pDeviceData->DriverCaps.pSupportedFormatOps = NULL;
+ }
+ if (pDeviceData->DriverCaps.pSupportedExtendedModes)
+ {
+ HeapFree(GetProcessHeap(), 0, pDeviceData->DriverCaps.pSupportedExtendedModes);
+ pDeviceData->DriverCaps.pSupportedExtendedModes = NULL;
+ }
+ if (pDeviceData->DriverCaps.pSupportedQueriesList)
+ {
+ HeapFree(GetProcessHeap(), 0, pDeviceData->DriverCaps.pSupportedQueriesList);
+ pDeviceData->DriverCaps.pSupportedQueriesList = NULL;
+ }
+
+ if (FALSE == CanReenableDirectDrawObject(pDeviceData->pUnknown6BC))
+ {
+ DPRINT1("Failed to re-enable DirectDrawObject");
+ ReleaseInternalDeviceData(pDeviceData);
+ return FALSE;
+ }
+
+ bRet = GetD3D9DriverInfo(
+ pDeviceData->pUnknown6BC,
+ &pDeviceData->DriverCaps,
+ &pDeviceData->_UnknownA8h,
+ pDeviceData->szDeviceName,
+ pDeviceData->hD3DRefDll,
+ &GlobalDriverData,
+ &D3dExtendedCaps,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &NumTextureFormats,
+ &NumStencilFormats,
+ &NumExtendedFormats,
+ &NumQueries
+ );
+
+ if (FALSE == bRet)
+ {
+ DPRINT1("Could not query DirectDrawObject, aborting");
+ ReleaseInternalDeviceData(pDeviceData);
+ return FALSE;
+ }
+
+ puD3dTextureFormats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, max(NumTextureFormats, 1) * sizeof(DDSURFACEDESC));
+ pD3dZStencilFormatList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, max(NumStencilFormats, 1) * sizeof(DDPIXELFORMAT));
+ pD3dDisplayModeList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, max(NumExtendedFormats, 1) * sizeof(D3DDISPLAYMODE));
+ pD3dQueryList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, max(NumQueries, 1) * sizeof(D3DQUERYTYPE));
+
+ bRet = GetD3D9DriverInfo(
+ pDeviceData->pUnknown6BC,
+ &pDeviceData->DriverCaps,
+ &pDeviceData->_UnknownA8h,
+ pDeviceData->szDeviceName,
+ pDeviceData->hD3DRefDll,
+ &GlobalDriverData,
+ &D3dExtendedCaps,
+ puD3dTextureFormats,
+ pD3dZStencilFormatList,
+ pD3dDisplayModeList,
+ pD3dQueryList,
+ &NumTextureFormats,
+ &NumStencilFormats,
+ &NumExtendedFormats,
+ &NumQueries
+ );
+
+ if (FALSE == bRet)
+ {
+ DPRINT1("Could not query DirectDrawObject, aborting");
+ HeapFree(GetProcessHeap(), 0, puD3dTextureFormats);
+ HeapFree(GetProcessHeap(), 0, pD3dZStencilFormatList);
+ HeapFree(GetProcessHeap(), 0, pD3dDisplayModeList);
+ HeapFree(GetProcessHeap(), 0, pD3dQueryList);
+ ReleaseInternalDeviceData(pDeviceData);
+ return FALSE;
+ }
+
+ pDeviceData->DriverCaps.NumSupportedFormatOps = NumTextureFormats;
+ if (NumTextureFormats > 0)
+ pDeviceData->DriverCaps.pSupportedFormatOps = puD3dTextureFormats;
+
+ pDeviceData->DriverCaps.NumSupportedExtendedModes = NumExtendedFormats;
+ if (NumExtendedFormats > 0)
+ pDeviceData->DriverCaps.pSupportedExtendedModes = pD3dDisplayModeList;
+
+ pDeviceData->DriverCaps.NumSupportedQueries = NumQueries;
+ if (NumQueries > 0)
+ pDeviceData->DriverCaps.pSupportedQueriesList = pD3dQueryList;
+
+ HeapFree(GetProcessHeap(), 0, pD3dZStencilFormatList);
+
+ return TRUE;
+}
+
+
+
+BOOL CanReenableDirectDrawObject(D3D9_Unknown6BC_INT* pUnknown)
+{
+ BOOL bDisplayModeWasChanged;
+
+ /* Try the real way first */
+ if (TRUE == OsThunkDdReenableDirectDrawObject(pUnknown->hDD, &bDisplayModeWasChanged))
+ return TRUE;
+
+ /* Ref types and software types can always be reenabled after a mode switch */
+ if (pUnknown->DeviceType == D3DDEVTYPE_REF || pUnknown->DeviceType == D3DDEVTYPE_SW)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+
+static void PrepareDriverInfoData(DD_GETDRIVERINFODATA* DrvInfo, LPVOID pData, DWORD dwExpectedSize)
+{
+ memset(DrvInfo, 0, sizeof(DD_GETDRIVERINFODATA));
+ DrvInfo->dwSize = sizeof(DD_GETDRIVERINFODATA);
+ DrvInfo->guidInfo = GUID_GetDriverInfo2;
+ DrvInfo->dwExpectedSize = dwExpectedSize;
+ DrvInfo->lpvData = pData;
+ DrvInfo->ddRVal = E_FAIL;
+}
+
+static void ResetGetDriverInfo2Data(DD_GETDRIVERINFO2DATA* DrvInfo2, DWORD dwType, DWORD dwExpectedSize)
+{
+ memset(DrvInfo2, 0, dwExpectedSize);
+ DrvInfo2->dwMagic = D3DGDI2_MAGIC;
+ DrvInfo2->dwType = dwType;
+ DrvInfo2->dwExpectedSize = dwExpectedSize;
+}
+
+BOOL GetD3D9DriverInfo( D3D9_Unknown6BC_INT* pUnknown6BC,
+ LPD3D9_DRIVERCAPS pDriverCaps,
+ D3D9_UnknownA8h_INT* pUnknownA8h,
+ LPCSTR lpszDeviceName,
+ HMODULE hD3dRefDll,
+ D3DHAL_GLOBALDRIVERDATA* pGblDriverData,
+ D3DHAL_D3DEXTENDEDCAPS* pD3dExtendedCaps,
+ LPDDSURFACEDESC puD3dTextureFormats,
+ DDPIXELFORMAT* pD3dZStencilFormatList,
+ D3DDISPLAYMODE* pD3dDisplayModeList,
+ D3DQUERYTYPE* pD3dQueryList,
+ LPDWORD pNumTextureFormats,
+ LPDWORD pNumZStencilFormats,
+ LPDWORD pNumExtendedFormats,
+ LPDWORD pNumQueries)
+{
+ BOOL bRet;
+ DWORD ValueSize;
+ DWORD dwDXVersion;
+
+ DD_HALINFO HalInfo;
+ DWORD CallBackFlags[3];
+ D3DNTHAL_CALLBACKS D3dCallbacks;
+ D3DNTHAL_GLOBALDRIVERDATA D3dDriverData;
+ DD_D3DBUFCALLBACKS D3dBufferCallbacks;
+ DWORD NumHeaps = 0;
+ DWORD NumFourCC = 0;
+
+ BOOL bDX8Mode = FALSE;
+
+ DD_GETDRIVERINFODATA DrvInfo;
+ DD_GETDDIVERSIONDATA DdiVersion;
+ DD_GETFORMATCOUNTDATA FormatCountData;
+ DD_GETEXTENDEDMODECOUNTDATA ExModeCountData;
+ DD_GETD3DQUERYCOUNTDATA D3dQueryCountData;
+
+ /* Init */
+ *pNumTextureFormats = 0;
+ *pNumZStencilFormats = 0;
+ *pNumExtendedFormats = 0;
+ *pNumQueries = 0;
+ memset(pD3dExtendedCaps, 0, sizeof(D3DHAL_D3DEXTENDEDCAPS));
+ memset(pGblDriverData, 0, sizeof(D3DHAL_GLOBALDRIVERDATA));
+ memset(pDriverCaps, 0, sizeof(D3D9_DRIVERCAPS));
+
+ /* Set runtime version */
+ ValueSize = sizeof(dwDXVersion);
+ if (FALSE == ReadRegistryValue(REG_DWORD, "DD_RUNTIME_VERSION", (LPBYTE)&dwDXVersion, &ValueSize))
+ dwDXVersion = DD_RUNTIME_VERSION;
+
+
+ bRet = OsThunkDdQueryDirectDrawObject(
+ pUnknown6BC->hDD,
+ &HalInfo,
+ CallBackFlags,
+ &D3dCallbacks,
+ &D3dDriverData,
+ &D3dBufferCallbacks,
+ NULL,
+ &NumHeaps,
+ NULL,
+ &NumFourCC,
+ NULL
+ );
+
+ if (bRet == FALSE)
+ {
+ /* TODO: Handle error */
+ return FALSE;
+ }
+
+ if ((HalInfo.ddCaps.dwSVBCaps2 & DDCAPS2_AUTOFLIPOVERLAY) == 0 &&
+ puD3dTextureFormats != NULL)
+ {
+ bRet = OsThunkDdQueryDirectDrawObject(
+ pUnknown6BC->hDD,
+ &HalInfo,
+ CallBackFlags,
+ &D3dCallbacks,
+ &D3dDriverData,
+ &D3dBufferCallbacks,
+ puD3dTextureFormats,
+ &NumHeaps,
+ NULL,
+ &NumFourCC,
+ NULL
+ );
+
+ if (FALSE == bRet)
+ return FALSE;
+ }
+
+ if (NULL == pUnknown6BC->swDDICreateDirectDrawObject)
+ {
+ *pNumTextureFormats = D3dDriverData.dwNumTextureFormats;
+ }
+
+ pDriverCaps->DriverCaps9.Caps = HalInfo.ddCaps.dwCaps;
+ pDriverCaps->DriverCaps9.Caps2 = HalInfo.ddCaps.dwCaps2;
+ pDriverCaps->DriverCaps9.Caps3 = HalInfo.ddCaps.dwSVCaps;
+ pDriverCaps->dwSVBCaps = HalInfo.ddCaps.dwSVBCaps;
+ pDriverCaps->dwVSBCaps = HalInfo.ddCaps.dwVSBCaps;
+ pDriverCaps->dwSVBCaps2 = HalInfo.ddCaps.dwSVBCaps2;
+ pUnknown6BC->lDisplayPitch = HalInfo.vmiData.lDisplayPitch;
+
+ if (HalInfo.dwFlags & DDHALINFO_GETDRIVERINFO2)
+ {
+ /* GUID_GetDriverInfo2 - Inform driver of DX version */
+ {
+ DD_DXVERSION DxVersion;
+
+ ResetGetDriverInfo2Data(&DxVersion.gdi2, D3DGDI2_TYPE_DXVERSION, sizeof(DD_DXVERSION));
+ DxVersion.dwDXVersion = dwDXVersion;
+
+ PrepareDriverInfoData(&DrvInfo, &DxVersion, sizeof(DxVersion));
+ OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo);
+ }
+
+
+ /* GUID_GetDriverInfo2 - Get DDI version */
+ {
+ ResetGetDriverInfo2Data(&DdiVersion.gdi2, D3DGDI2_TYPE_GETDDIVERSION, sizeof(DD_GETDDIVERSIONDATA));
+ PrepareDriverInfoData(&DrvInfo, &DdiVersion, sizeof(DdiVersion));
+ bRet = OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo);
+
+ if (DdiVersion.dwDDIVersion != DX9_DDI_VERSION)
+ {
+ DWORD ForceDDIOn;
+
+ ValueSize = sizeof(ForceDDIOn);
+ if (TRUE == ReadRegistryValue(REG_DWORD, "ForceOldDDIOn", (LPBYTE)&ForceDDIOn, &ValueSize) &&
+ 0 != ForceDDIOn)
+ {
+ DdiVersion.dwDDIVersion = DX9_DDI_VERSION;
+ }
+ }
+ }
+
+
+ /* Check for errors to fallback to DX8 mode */
+ if (DdiVersion.dwDDIVersion < DX9_DDI_VERSION)
+ {
+ bDX8Mode = TRUE;
+
+ if (DdiVersion.dwDDIVersion == 0)
+ {
+ DPRINT1("Driver claims to be DX9 driver, but didn't report DX9 DDI version - reverting to DX8 mode");
+ }
+ else
+ {
+ DPRINT1("Driver claims to be DX9 driver, but was built with an old DDI version - reverting to DX8 mode");
+ }
+
+ /* GUID_GetDriverInfo2 - Get D3DCAPS8 */
+ {
+ D3DCAPS8 DriverCaps8;
+
+ ResetGetDriverInfo2Data((DD_GETDRIVERINFO2DATA*)&DriverCaps8, D3DGDI2_TYPE_GETD3DCAPS8, sizeof(D3DCAPS8));
+ PrepareDriverInfoData(&DrvInfo, &DriverCaps8, sizeof(D3DCAPS8));
+
+ if (FALSE == OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo) ||
+ S_OK != DrvInfo.ddRVal ||
+ DrvInfo.dwActualSize != sizeof(D3DCAPS8))
+ {
+ DPRINT1("Driver returned an invalid D3DCAPS8 structure - aborting");
+ return FALSE;
+ }
+
+ memcpy(&pDriverCaps->DriverCaps9, &DriverCaps8, sizeof(D3DCAPS8));
+ pDriverCaps->DriverCaps9.Caps = HalInfo.ddCaps.dwCaps;
+ }
+ }
+
+
+ /* GUID_GetDriverInfo2 - Get D3DCAPS9 */
+ if (FALSE == bDX8Mode)
+ {
+ D3DCAPS9 DriverCaps9;
+
+ ResetGetDriverInfo2Data((DD_GETDRIVERINFO2DATA*)&DriverCaps9, D3DGDI2_TYPE_GETD3DCAPS9, sizeof(D3DCAPS9));
+ PrepareDriverInfoData(&DrvInfo, &DriverCaps9, sizeof(D3DCAPS9));
+
+ if (FALSE == OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo) ||
+ S_OK != DrvInfo.ddRVal ||
+ DrvInfo.dwActualSize != sizeof(D3DCAPS9))
+ {
+ DPRINT1("Driver returned an invalid D3DCAPS9 structure - aborting");
+ return FALSE;
+ }
+
+ pDriverCaps->DriverCaps9 = DriverCaps9;
+ pDriverCaps->DriverCaps9.Caps = HalInfo.ddCaps.dwCaps;
+ }
+
+
+ /* GUID_GetDriverInfo2 - Get format count data */
+ {
+ ResetGetDriverInfo2Data(&FormatCountData.gdi2, D3DGDI2_TYPE_GETFORMATCOUNT, sizeof(DD_GETFORMATCOUNTDATA));
+ PrepareDriverInfoData(&DrvInfo, &FormatCountData, sizeof(DD_GETFORMATCOUNTDATA));
+ FormatCountData.dwFormatCount = UINT_MAX;
+ FormatCountData.dwReserved = dwDXVersion;
+
+ if (TRUE == OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo))
+ {
+ if (DrvInfo.ddRVal != S_OK)
+ {
+ DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI_TYPE_GETFORMATCOUNT in GetDriverInfo call");
+ return FALSE;
+ }
+ else if (DrvInfo.dwActualSize != sizeof(DD_GETFORMATCOUNTDATA))
+ {
+ DPRINT1("Driver returned an invalid DD_GETFORMATCOUNTDATA structure - aborting");
+ return FALSE;
+ }
+ else if (FormatCountData.dwFormatCount == UINT_MAX)
+ {
+ DPRINT1("Driver didn't set DD_GETFORMATCOUNTDATA.dwFormatCount - aborting");
+ return FALSE;
+ }
+
+ *pNumTextureFormats = FormatCountData.dwFormatCount;
+ }
+ }
+
+ /* GUID_GetDriverInfo2 - Get format data */
+ if (puD3dTextureFormats != NULL)
+ {
+ DWORD FormatIndex;
+ DD_GETFORMATDATA FormatData;
+
+ for (FormatIndex = 0; FormatIndex < FormatCountData.dwFormatCount; FormatIndex++)
+ {
+ ResetGetDriverInfo2Data(&FormatData.gdi2, D3DGDI2_TYPE_GETFORMAT, sizeof(DD_GETFORMATDATA));
+ PrepareDriverInfoData(&DrvInfo, &FormatData, sizeof(DD_GETFORMATDATA));
+ FormatData.dwFormatIndex = FormatIndex;
+
+ if (TRUE == OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo))
+ {
+ if (DrvInfo.ddRVal != S_OK)
+ {
+ DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI_TYPE_GETFORMAT in GetDriverInfo call");
+ return FALSE;
+ }
+ else if (DrvInfo.dwActualSize != sizeof(DD_GETFORMATDATA))
+ {
+ DPRINT1("Driver returned an invalid DD_GETFORMATDATA structure - aborting");
+ return FALSE;
+ }
+ else if (FormatData.format.dwSize != sizeof(DDPIXELFORMAT))
+ {
+ DPRINT1("Driver didn't set DD_GETFORMATDATA.format - aborting");
+ return FALSE;
+ }
+
+ /* Copy format data to puD3dTextureFormats */
+ memset(puD3dTextureFormats, 0, sizeof(DDSURFACEDESC));
+ puD3dTextureFormats->dwSize = sizeof(DDSURFACEDESC);
+ puD3dTextureFormats->dwFlags = DDSD_PIXELFORMAT;
+ memcpy(&puD3dTextureFormats->ddpfPixelFormat, &FormatData.format, sizeof(DDPIXELFORMAT));
+
+ if ((FormatData.format.dwOperations & D3DFORMAT_OP_PIXELSIZE) != 0 &&
+ FormatData.format.dwPrivateFormatBitCount > 0)
+ {
+ /* TODO: Register driver's own pixelformat */
+ }
+
+ ++puD3dTextureFormats;
+ }
+ }
+ }
+
+ /* GUID_GetDriverInfo2 - Get extended mode count data */
+ {
+ ResetGetDriverInfo2Data(&ExModeCountData.gdi2, D3DGDI2_TYPE_GETEXTENDEDMODECOUNT, sizeof(DD_GETEXTENDEDMODECOUNTDATA));
+ PrepareDriverInfoData(&DrvInfo, &ExModeCountData, sizeof(DD_GETEXTENDEDMODECOUNTDATA));
+ ExModeCountData.dwModeCount = UINT_MAX;
+ ExModeCountData.dwReserved = dwDXVersion;
+
+ if (TRUE == OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo))
+ {
+ if (DrvInfo.ddRVal == S_OK)
+ {
+ if (DrvInfo.dwActualSize != sizeof(DD_GETEXTENDEDMODECOUNTDATA))
+ {
+ DPRINT1("Driver returned an invalid DD_GETEXTENDEDFORMATCOUNTDATA structure - aborting");
+ return FALSE;
+ }
+ else if (ExModeCountData.dwModeCount == UINT_MAX)
+ {
+ DPRINT1("Driver didn't set DD_GETEXTENDEDMODECOUNTDATA.dwModeCount - aborting");
+ return FALSE;
+ }
+
+ *pNumExtendedFormats = ExModeCountData.dwModeCount;
+ }
+ else
+ {
+ ExModeCountData.dwModeCount = 0;
+ }
+ }
+ }
+
+ /* GUID_GetDriverInfo2 - Get extended mode data */
+ if (pD3dDisplayModeList != NULL)
+ {
+ DWORD ModeIndex;
+ DD_GETEXTENDEDMODEDATA ExModeData;
+
+ for (ModeIndex = 0; ModeIndex < ExModeCountData.dwModeCount; ModeIndex++)
+ {
+ ResetGetDriverInfo2Data(&ExModeData.gdi2, D3DGDI2_TYPE_GETEXTENDEDMODE, sizeof(DD_GETEXTENDEDMODEDATA));
+ PrepareDriverInfoData(&DrvInfo, &ExModeData, sizeof(DD_GETEXTENDEDMODEDATA));
+ ExModeData.dwModeIndex = ModeIndex;
+ ExModeData.mode.Width = UINT_MAX;
+
+ if (TRUE == OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo))
+ {
+ if (DrvInfo.ddRVal != S_OK)
+ {
+ DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI2_TYPE_GETEXTENDEDMODE in GetDriverInfo call");
+ return FALSE;
+ }
+ else if (DrvInfo.dwActualSize != sizeof(DD_GETEXTENDEDMODEDATA))
+ {
+ DPRINT1("Driver returned an invalid DD_GETEXTENDEDMODEDATA structure - aborting");
+ return FALSE;
+ }
+ else if (ExModeData.mode.Width != UINT_MAX)
+ {
+ DPRINT1("Driver didn't set DD_GETEXTENDEDMODEDATA.mode - aborting");
+ return FALSE;
+ }
+
+ memcpy(pD3dDisplayModeList, &ExModeData.mode, sizeof(D3DDISPLAYMODE));
+ ++pD3dDisplayModeList;
+ }
+ }
+ }
+
+ /* GUID_GetDriverInfo2 - Get adapter group */
+ {
+ DD_GETADAPTERGROUPDATA AdapterGroupData;
+ ResetGetDriverInfo2Data(&AdapterGroupData.gdi2, D3DGDI2_TYPE_GETADAPTERGROUP, sizeof(DD_GETADAPTERGROUPDATA));
+ PrepareDriverInfoData(&DrvInfo, &AdapterGroupData, sizeof(DD_GETADAPTERGROUPDATA));
+ AdapterGroupData.ulUniqueAdapterGroupId = UINT_MAX;
+
+ if (TRUE == OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo))
+ {
+ if (DrvInfo.ddRVal != S_OK)
+ {
+ DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI2_TYPE_GETADAPTERGROUP in GetDriverInfo call");
+ return FALSE;
+ }
+ else if (DrvInfo.dwActualSize != sizeof(DD_GETADAPTERGROUPDATA))
+ {
+ DPRINT1("Driver returned an invalid DD_GETADAPTERGROUPDATA structure - aborting");
+ return FALSE;
+ }
+ else if (AdapterGroupData.ulUniqueAdapterGroupId == UINT_MAX)
+ {
+ DPRINT1("Driver didn't set DD_GETADAPTERGROUPDATA.ulUniqueAdapterGroupId - aborting");
+ return FALSE;
+ }
+
+ pDriverCaps->ulUniqueAdapterGroupId = (ULONG)AdapterGroupData.ulUniqueAdapterGroupId;
+ }
+ }
+
+ /* GUID_GetDriverInfo2 - Query count data */
+ {
+ ResetGetDriverInfo2Data(&D3dQueryCountData.gdi2, D3DGDI2_TYPE_GETD3DQUERYCOUNT, sizeof(DD_GETD3DQUERYCOUNTDATA));
+ PrepareDriverInfoData(&DrvInfo, &D3dQueryCountData, sizeof(DD_GETD3DQUERYCOUNTDATA));
+ D3dQueryCountData.dwNumQueries = UINT_MAX;
+
+ if (TRUE == OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo))
+ {
+ if (DrvInfo.ddRVal != S_OK)
+ {
+ DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI2_TYPE_GETD3DQUERYCOUNT in GetDriverInfo call");
+ return FALSE;
+ }
+ else if (DrvInfo.dwActualSize != sizeof(DD_GETD3DQUERYCOUNTDATA))
+ {
+ DPRINT1("Driver returned an invalid DD_GETD3DQUERYCOUNTDATA structure - aborting");
+ return FALSE;
+ }
+ else if (D3dQueryCountData.dwNumQueries == UINT_MAX)
+ {
+ DPRINT1("Driver didn't set DD_GETD3DQUERYCOUNTDATA.dwNumQueries - aborting");
+ return FALSE;
+ }
+
+ *pNumQueries = D3dQueryCountData.dwNumQueries;
+ }
+ }
+
+ /* GUID_GetDriverInfo2 - Query data */
+ if (pD3dQueryList != NULL)
+ {
+ DWORD QueryIndex;
+ DD_GETD3DQUERYDATA D3dQueryData;
+
+ for (QueryIndex = 0; QueryIndex < D3dQueryCountData.dwNumQueries; QueryIndex++)
+ {
+ ResetGetDriverInfo2Data(&D3dQueryData.gdi2, D3DGDI2_TYPE_GETD3DQUERY, sizeof(DD_GETD3DQUERYDATA));
+ PrepareDriverInfoData(&DrvInfo, &D3dQueryData, sizeof(DD_GETD3DQUERYDATA));
+ D3dQueryData.dwQueryIndex = QueryIndex;
+
+ if (TRUE == OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo))
+ {
+ if (DrvInfo.ddRVal != S_OK)
+ {
+ DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI2_TYPE_GETD3DQUERY in GetDriverInfo call");
+ return FALSE;
+ }
+ else if (DrvInfo.dwActualSize != sizeof(DD_GETD3DQUERYDATA))
+ {
+ DPRINT1("Driver returned an invalid DD_GETD3DQUERYDATA structure - aborting");
+ return FALSE;
+ }
+
+ *pD3dQueryList = D3dQueryData.QueryType;
+ ++pD3dQueryList;
+ }
+ }
+ }
+ }
+
+ /* D3dDriverData -> pGblDriverData */
+ memcpy(&pGblDriverData->hwCaps, &D3dDriverData.hwCaps, sizeof(D3DNTHALDEVICEDESC_V1));
+ pGblDriverData->dwNumVertices = D3dDriverData.dwNumVertices;
+ pGblDriverData->dwNumClipVertices = D3dDriverData.dwNumClipVertices;
+
+ /* GUID_D3DExtendedCaps */
+ {
+ DrvInfo.dwSize = sizeof(DD_GETDRIVERINFODATA);
+ DrvInfo.guidInfo = GUID_D3DExtendedCaps;
+ DrvInfo.dwExpectedSize = sizeof(D3DHAL_D3DEXTENDEDCAPS);
+ DrvInfo.lpvData = pD3dExtendedCaps;
+ bRet = OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo);
+
+ if (TRUE != bRet || DrvInfo.ddRVal != S_OK)
+ {
+ DPRINT1("Driver failed call to GetDriverInfo() with: GUID_D3DExtendedCaps");
+ return FALSE;
+ }
+ }
+
+ /* GUID_ZPixelFormats */
+ {
+ DDPIXELFORMAT *pZPixelFormats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FormatCountData.dwFormatCount * sizeof(DDPIXELFORMAT));
+
+ DrvInfo.dwSize = sizeof(DD_GETDRIVERINFODATA);
+ DrvInfo.guidInfo = GUID_ZPixelFormats;
+ DrvInfo.dwExpectedSize = FormatCountData.dwFormatCount * sizeof(DDPIXELFORMAT);
+ DrvInfo.lpvData = pZPixelFormats;
+ bRet = OsThunkDdGetDriverInfo((HANDLE)pUnknown6BC->hDD, &DrvInfo);
+
+ if (TRUE != bRet || DrvInfo.ddRVal != S_OK)
+ {
+ DPRINT1("Driver failed call to GetDriverInfo() with: GUID_ZPixelFormats");
+ HeapFree(GetProcessHeap(), 0, pZPixelFormats);
+ return FALSE;
+ }
+
+ *pNumZStencilFormats = FormatCountData.dwFormatCount;
+
+ if (pD3dZStencilFormatList != NULL)
+ memcpy(pD3dZStencilFormatList, pZPixelFormats, FormatCountData.dwFormatCount * sizeof(DDPIXELFORMAT));
+
+ HeapFree(GetProcessHeap(), 0, pZPixelFormats);
+ }
+
+ /* Get current display format */
+ {
+ D3DDISPLAYMODE CurrentDisplayMode;
+ GetAdapterMode(lpszDeviceName, &CurrentDisplayMode);
+ pUnknown6BC->RawDisplayFormat = CurrentDisplayMode.Format;
+ pUnknown6BC->DisplayFormat = CurrentDisplayMode.Format;
+
+ if ((HalInfo.vmiData.ddpfDisplay.dwFlags & DDPF_ALPHAPIXELS) != 0)
+ {
+ if (CurrentDisplayMode.Format == D3DFMT_X8R8G8B8)
+ {
+ pUnknown6BC->DisplayFormat = D3DFMT_A8R8G8B8;
+ }
+ else if (CurrentDisplayMode.Format == D3DFMT_X1R5G5B5)
+ {
+ pUnknown6BC->DisplayFormat = D3DFMT_A1R5G5B5;
+ }
+ }
+
+ pDriverCaps->dwDisplayWidth = CurrentDisplayMode.Width;
+ pDriverCaps->dwDisplayHeight = CurrentDisplayMode.Height;
+ pDriverCaps->RawDisplayFormat = CurrentDisplayMode.Format;
+ pDriverCaps->DisplayFormat = pUnknown6BC->DisplayFormat;
+ pDriverCaps->dwRefreshRate = CurrentDisplayMode.RefreshRate;
+ }
+
+ /* TODO: Set all internal function pointers to create surface, etc. */
+
+ /* Set device rect */
+ {
+ HMONITOR hMonitor;
+ MONITORINFO MonitorInfo;
+
+ memset(&MonitorInfo, 0, sizeof(MONITORINFO));
+ MonitorInfo.cbSize = sizeof(MONITORINFO);
+
+ hMonitor = GetAdapterMonitor(lpszDeviceName);
+ if (TRUE == GetMonitorInfoA(hMonitor, &MonitorInfo))
+ {
+ pUnknown6BC->DeviceRect = MonitorInfo.rcMonitor;
+ }
+ else
+ {
+ DPRINT1("Could not get monitor information");
+ }
+ }
+
+ pUnknown6BC->dwCaps = pDriverCaps->DriverCaps9.Caps;
+ pUnknown6BC->dwSVBCaps = pDriverCaps->dwSVBCaps;
+
+ if (FALSE == bDX8Mode)
+ {
+ pUnknown6BC->MajorDxVersion = 9;
+
+ if (0 != (pDriverCaps->DriverCaps9.VertexProcessingCaps & D3DVTXPCAPS_NO_VSDT_UBYTE4))
+ {
+ DPRINT1("Driver claimed to be DX9 driver, but used depricated D3DCAPS9.VertexProcessingCaps: D3DVTXPCAPS_NO_VSDT_UBYTE4 instead of not setting D3DCAPS9.DeclTypes: D3DDTCAPS_UBYTE4.");
+ return FALSE;
+ }
+ }
+ else
+ {
+ pUnknown6BC->MajorDxVersion = 8;
+
+ if (0 == (pDriverCaps->DriverCaps9.VertexProcessingCaps & D3DVTXPCAPS_NO_VSDT_UBYTE4))
+ {
+ pDriverCaps->DriverCaps9.DeclTypes |= D3DDTCAPS_UBYTE4;
+ pDriverCaps->DriverCaps9.VertexProcessingCaps &= ~D3DVTXPCAPS_NO_VSDT_UBYTE4;
+ }
+ }
+
+ return TRUE;
+}