1 #include <d3d9.h> 2 #include <ddraw.h> 3 #include <d3dnthal.h> 4 #include <d3dhal.h> 5 #include <ddrawi.h> 6 #include <ddrawgdi.h> 7 #include <dll/directx/d3d8thk.h> 8 #include <debug.h> 9 #include <limits.h> 10 #include "d3d9_helpers.h" 11 #include "d3d9_caps.h" 12 #include "adapter.h" 13 #include "d3d9_callbacks.h" 14 15 static INT g_NumDevices = 0; 16 17 void CreateDisplayModeList(LPCSTR lpszDeviceName, D3DDISPLAYMODE* pDisplayModes, DWORD* pNumDisplayModes, D3DFORMAT Default16BitFormat, D3D9_Unknown6BC* pUnknown6BC) 18 { 19 DEVMODEA DevMode; 20 DWORD ModeIndex = 0; 21 DWORD ValidModes = 0; 22 23 while (TRUE == EnumDisplaySettingsA(lpszDeviceName, ModeIndex, &DevMode)) 24 { 25 D3DFORMAT DefaultFormat; 26 27 if (DevMode.dmBitsPerPel != 15 && 28 DevMode.dmBitsPerPel != 16 && 29 DevMode.dmBitsPerPel != 32) 30 { 31 ++ModeIndex; 32 continue; 33 } 34 35 ++ValidModes; 36 37 if (DevMode.dmBitsPerPel == 15 || DevMode.dmBitsPerPel == 16) 38 { 39 if (NULL == pUnknown6BC) 40 { 41 ++ModeIndex; 42 continue; 43 } 44 45 DefaultFormat = Default16BitFormat; 46 } 47 else 48 { 49 DefaultFormat = D3DFMT_X8R8G8B8; 50 } 51 52 if (NULL != pDisplayModes) 53 { 54 if (ValidModes == *pNumDisplayModes) 55 break; 56 57 pDisplayModes->Width = DevMode.dmPelsWidth; 58 pDisplayModes->Height = DevMode.dmPelsHeight; 59 pDisplayModes->RefreshRate = DevMode.dmDisplayFrequency; 60 pDisplayModes->Format = DefaultFormat; 61 ++pDisplayModes; 62 } 63 64 ++ModeIndex; 65 } 66 67 *pNumDisplayModes = ValidModes; 68 } 69 70 static void CreateInternalDeviceData(HDC hDC, LPCSTR lpszDeviceName, D3D9_Unknown6BC** ppUnknown, D3DDEVTYPE DeviceType, HMODULE* hD3DRefDll) 71 { 72 D3D9_Unknown6BC* pUnknown6BC; 73 DWORD ValueSize; 74 75 if (ppUnknown) *ppUnknown = NULL; 76 if (hD3DRefDll) *hD3DRefDll = NULL; 77 78 if (DeviceType != D3DDEVTYPE_HAL) 79 { 80 /* TODO: Implement D3DDEVTYPE_REF and D3DDEVTYPE_SW */ 81 UNIMPLEMENTED; 82 return; 83 } 84 85 pUnknown6BC = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3D9_Unknown6BC)); 86 if (NULL == pUnknown6BC) 87 { 88 DPRINT1("Out of memory"); 89 return; 90 } 91 92 pUnknown6BC->hDirectDrawLocal = OsThunkDdCreateDirectDrawObject(hDC); 93 if (0 == pUnknown6BC->hDirectDrawLocal) 94 { 95 HeapFree(GetProcessHeap(), 0, pUnknown6BC); 96 return; 97 } 98 99 100 SafeCopyString(pUnknown6BC->szDeviceName, CCHDEVICENAME, lpszDeviceName); 101 //pUnknown6BC->DeviceUniq = DdQueryDisplaySettingsUniqueness(); 102 pUnknown6BC->DeviceType = DeviceType; 103 104 105 ValueSize = sizeof(DWORD); 106 ReadRegistryValue(REG_DWORD, "ForceDriverFlagsOn", (LPBYTE)&pUnknown6BC->bForceDriverFlagsOn, &ValueSize); 107 108 ValueSize = sizeof(DWORD); 109 ReadRegistryValue(REG_DWORD, "ForceDriverFlagsOff", (LPBYTE)&pUnknown6BC->bForceDriverFlagsOff, &ValueSize); 110 111 ++g_NumDevices; 112 113 *ppUnknown = pUnknown6BC; 114 } 115 116 static void ReleaseInternalDeviceData(LPD3D9_DEVICEDATA pDeviceData) 117 { 118 OsThunkDdDeleteDirectDrawObject(pDeviceData->pUnknown6BC->hDirectDrawLocal); 119 120 HeapFree(GetProcessHeap(), 0, pDeviceData->pUnknown6BC); 121 pDeviceData->pUnknown6BC = NULL; 122 123 --g_NumDevices; 124 } 125 126 BOOL GetDeviceData(LPD3D9_DEVICEDATA pDeviceData) 127 { 128 BOOL bRet; 129 D3DHAL_GLOBALDRIVERDATA GlobalDriverData; 130 D3DHAL_D3DEXTENDEDCAPS D3dExtendedCaps; 131 LPDDSURFACEDESC puD3dTextureFormats; 132 DDPIXELFORMAT* pD3dZStencilFormatList; 133 D3DDISPLAYMODE* pD3dDisplayModeList; 134 D3DQUERYTYPE* pD3dQueryList; 135 DWORD NumTextureFormats = 0; 136 DWORD NumStencilFormats = 0; 137 DWORD NumExtendedFormats = 0; 138 DWORD NumQueries = 0; 139 140 if (NULL == pDeviceData->pUnknown6BC) 141 { 142 CreateInternalDeviceData( 143 pDeviceData->hDC, 144 pDeviceData->szDeviceName, 145 &pDeviceData->pUnknown6BC, 146 pDeviceData->DeviceType, 147 &pDeviceData->hD3DRefDll 148 ); 149 150 if (NULL == pDeviceData->pUnknown6BC) 151 { 152 DPRINT1("Failed to create DirectDrawObject for Direct3D9"); 153 return FALSE; 154 } 155 } 156 else 157 { 158 D3D9_DRIVERCAPS DriverCaps; 159 D3D9_CALLBACKS D3D9Callbacks; 160 161 if (FALSE == CanReenableDirectDrawObject(pDeviceData->pUnknown6BC)) 162 { 163 DPRINT1("Failed to re-enable DirectDrawObject"); 164 return FALSE; 165 } 166 167 bRet = GetD3D9DriverInfo( 168 pDeviceData->pUnknown6BC, 169 &DriverCaps, 170 &D3D9Callbacks, 171 pDeviceData->szDeviceName, 172 pDeviceData->hD3DRefDll, 173 &GlobalDriverData, 174 &D3dExtendedCaps, 175 NULL, 176 NULL, 177 NULL, 178 NULL, 179 &NumTextureFormats, 180 &NumStencilFormats, 181 &NumExtendedFormats, 182 &NumQueries 183 ); 184 185 if (TRUE == bRet) 186 { 187 pDeviceData->DriverCaps.dwDisplayWidth = DriverCaps.dwDisplayWidth; 188 pDeviceData->DriverCaps.dwDisplayHeight = DriverCaps.dwDisplayHeight; 189 pDeviceData->DriverCaps.RawDisplayFormat = DriverCaps.RawDisplayFormat; 190 pDeviceData->DriverCaps.DisplayFormat = DriverCaps.DisplayFormat; 191 pDeviceData->DriverCaps.dwRefreshRate = DriverCaps.dwRefreshRate; 192 } 193 194 return bRet; 195 } 196 197 /* Cleanup of old stuff */ 198 if (pDeviceData->DriverCaps.pSupportedFormatOps) 199 { 200 HeapFree(GetProcessHeap(), 0, pDeviceData->DriverCaps.pSupportedFormatOps); 201 pDeviceData->DriverCaps.pSupportedFormatOps = NULL; 202 } 203 if (pDeviceData->DriverCaps.pSupportedExtendedModes) 204 { 205 HeapFree(GetProcessHeap(), 0, pDeviceData->DriverCaps.pSupportedExtendedModes); 206 pDeviceData->DriverCaps.pSupportedExtendedModes = NULL; 207 } 208 if (pDeviceData->DriverCaps.pSupportedQueriesList) 209 { 210 HeapFree(GetProcessHeap(), 0, pDeviceData->DriverCaps.pSupportedQueriesList); 211 pDeviceData->DriverCaps.pSupportedQueriesList = NULL; 212 } 213 214 if (FALSE == CanReenableDirectDrawObject(pDeviceData->pUnknown6BC)) 215 { 216 DPRINT1("Failed to re-enable DirectDrawObject"); 217 ReleaseInternalDeviceData(pDeviceData); 218 return FALSE; 219 } 220 221 bRet = GetD3D9DriverInfo( 222 pDeviceData->pUnknown6BC, 223 &pDeviceData->DriverCaps, 224 &pDeviceData->D3D9Callbacks, 225 pDeviceData->szDeviceName, 226 pDeviceData->hD3DRefDll, 227 &GlobalDriverData, 228 &D3dExtendedCaps, 229 NULL, 230 NULL, 231 NULL, 232 NULL, 233 &NumTextureFormats, 234 &NumStencilFormats, 235 &NumExtendedFormats, 236 &NumQueries 237 ); 238 239 if (FALSE == bRet) 240 { 241 DPRINT1("Could not query DirectDrawObject, aborting"); 242 ReleaseInternalDeviceData(pDeviceData); 243 return FALSE; 244 } 245 246 puD3dTextureFormats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, max(NumTextureFormats, 1) * sizeof(DDSURFACEDESC)); 247 pD3dZStencilFormatList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, max(NumStencilFormats, 1) * sizeof(DDPIXELFORMAT)); 248 pD3dDisplayModeList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, max(NumExtendedFormats, 1) * sizeof(D3DDISPLAYMODE)); 249 pD3dQueryList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, max(NumQueries, 1) * sizeof(D3DQUERYTYPE)); 250 251 bRet = GetD3D9DriverInfo( 252 pDeviceData->pUnknown6BC, 253 &pDeviceData->DriverCaps, 254 &pDeviceData->D3D9Callbacks, 255 pDeviceData->szDeviceName, 256 pDeviceData->hD3DRefDll, 257 &GlobalDriverData, 258 &D3dExtendedCaps, 259 puD3dTextureFormats, 260 pD3dZStencilFormatList, 261 pD3dDisplayModeList, 262 pD3dQueryList, 263 &NumTextureFormats, 264 &NumStencilFormats, 265 &NumExtendedFormats, 266 &NumQueries 267 ); 268 269 if (FALSE == bRet) 270 { 271 DPRINT1("Could not query DirectDrawObject, aborting"); 272 HeapFree(GetProcessHeap(), 0, puD3dTextureFormats); 273 HeapFree(GetProcessHeap(), 0, pD3dZStencilFormatList); 274 HeapFree(GetProcessHeap(), 0, pD3dDisplayModeList); 275 HeapFree(GetProcessHeap(), 0, pD3dQueryList); 276 ReleaseInternalDeviceData(pDeviceData); 277 return FALSE; 278 } 279 280 pDeviceData->DriverCaps.NumSupportedFormatOps = NumTextureFormats; 281 if (NumTextureFormats > 0) 282 pDeviceData->DriverCaps.pSupportedFormatOps = puD3dTextureFormats; 283 284 pDeviceData->DriverCaps.NumSupportedExtendedModes = NumExtendedFormats; 285 if (NumExtendedFormats > 0) 286 pDeviceData->DriverCaps.pSupportedExtendedModes = pD3dDisplayModeList; 287 288 pDeviceData->DriverCaps.NumSupportedQueries = NumQueries; 289 if (NumQueries > 0) 290 pDeviceData->DriverCaps.pSupportedQueriesList = pD3dQueryList; 291 292 HeapFree(GetProcessHeap(), 0, pD3dZStencilFormatList); 293 294 return TRUE; 295 } 296 297 298 299 BOOL CanReenableDirectDrawObject(D3D9_Unknown6BC* pUnknown) 300 { 301 BOOL bDisplayModeWasChanged; 302 303 /* Try the real way first */ 304 if (TRUE == OsThunkDdReenableDirectDrawObject(pUnknown->hDirectDrawLocal, &bDisplayModeWasChanged)) 305 return TRUE; 306 307 /* Ref types and software types can always be reenabled after a mode switch */ 308 if (pUnknown->DeviceType == D3DDEVTYPE_REF || pUnknown->DeviceType == D3DDEVTYPE_SW) 309 return TRUE; 310 311 return FALSE; 312 } 313 314 315 316 static void PrepareDriverInfoData(DD_GETDRIVERINFODATA* DrvInfo, LPVOID pData, DWORD dwExpectedSize) 317 { 318 memset(DrvInfo, 0, sizeof(DD_GETDRIVERINFODATA)); 319 DrvInfo->dwSize = sizeof(DD_GETDRIVERINFODATA); 320 DrvInfo->guidInfo = GUID_GetDriverInfo2; 321 DrvInfo->dwExpectedSize = dwExpectedSize; 322 DrvInfo->lpvData = pData; 323 DrvInfo->ddRVal = E_FAIL; 324 } 325 326 static void ResetGetDriverInfo2Data(DD_GETDRIVERINFO2DATA* DrvInfo2, DWORD dwType, DWORD dwExpectedSize) 327 { 328 memset(DrvInfo2, 0, dwExpectedSize); 329 DrvInfo2->dwMagic = D3DGDI2_MAGIC; 330 DrvInfo2->dwType = dwType; 331 DrvInfo2->dwExpectedSize = dwExpectedSize; 332 } 333 334 BOOL GetD3D9DriverInfo( D3D9_Unknown6BC* pUnknown6BC, 335 LPD3D9_DRIVERCAPS pDriverCaps, 336 D3D9_CALLBACKS* pD3D9Callbacks, 337 LPCSTR lpszDeviceName, 338 HMODULE hD3dRefDll, 339 D3DHAL_GLOBALDRIVERDATA* pGblDriverData, 340 D3DHAL_D3DEXTENDEDCAPS* pD3dExtendedCaps, 341 LPDDSURFACEDESC puD3dTextureFormats, 342 DDPIXELFORMAT* pD3dZStencilFormatList, 343 D3DDISPLAYMODE* pD3dDisplayModeList, 344 D3DQUERYTYPE* pD3dQueryList, 345 LPDWORD pNumTextureFormats, 346 LPDWORD pNumZStencilFormats, 347 LPDWORD pNumExtendedFormats, 348 LPDWORD pNumQueries) 349 { 350 BOOL bRet; 351 DWORD ValueSize; 352 DWORD dwDXVersion; 353 354 DD_HALINFO HalInfo; 355 DWORD CallBackFlags[3]; 356 D3DNTHAL_CALLBACKS D3dCallbacks; 357 D3DNTHAL_GLOBALDRIVERDATA D3dDriverData; 358 DD_D3DBUFCALLBACKS D3dBufferCallbacks; 359 DWORD NumHeaps = 0; 360 DWORD NumFourCC = 0; 361 362 BOOL bDX8Mode = FALSE; 363 364 DD_GETDRIVERINFODATA DrvInfo; 365 DD_GETDDIVERSIONDATA DdiVersion; 366 DD_GETFORMATCOUNTDATA FormatCountData; 367 DD_GETEXTENDEDMODECOUNTDATA ExModeCountData; 368 DD_GETD3DQUERYCOUNTDATA D3dQueryCountData; 369 370 /* Init */ 371 *pNumTextureFormats = 0; 372 *pNumZStencilFormats = 0; 373 *pNumExtendedFormats = 0; 374 *pNumQueries = 0; 375 memset(pD3dExtendedCaps, 0, sizeof(D3DHAL_D3DEXTENDEDCAPS)); 376 memset(pGblDriverData, 0, sizeof(D3DHAL_GLOBALDRIVERDATA)); 377 memset(pDriverCaps, 0, sizeof(D3D9_DRIVERCAPS)); 378 379 /* Set runtime version */ 380 ValueSize = sizeof(dwDXVersion); 381 if (FALSE == ReadRegistryValue(REG_DWORD, "DD_RUNTIME_VERSION", (LPBYTE)&dwDXVersion, &ValueSize)) 382 dwDXVersion = DD_RUNTIME_VERSION; 383 384 385 bRet = OsThunkDdQueryDirectDrawObject( 386 pUnknown6BC->hDirectDrawLocal, 387 &HalInfo, 388 CallBackFlags, 389 &D3dCallbacks, 390 &D3dDriverData, 391 &D3dBufferCallbacks, 392 NULL, 393 &NumHeaps, 394 NULL, 395 &NumFourCC, 396 NULL 397 ); 398 399 if (bRet == FALSE) 400 { 401 /* TODO: Handle error */ 402 return FALSE; 403 } 404 405 if ((HalInfo.ddCaps.dwSVBCaps2 & DDCAPS2_AUTOFLIPOVERLAY) == 0 && 406 puD3dTextureFormats != NULL) 407 { 408 bRet = OsThunkDdQueryDirectDrawObject( 409 pUnknown6BC->hDirectDrawLocal, 410 &HalInfo, 411 CallBackFlags, 412 &D3dCallbacks, 413 &D3dDriverData, 414 &D3dBufferCallbacks, 415 puD3dTextureFormats, 416 &NumHeaps, 417 NULL, 418 &NumFourCC, 419 NULL 420 ); 421 422 if (FALSE == bRet) 423 return FALSE; 424 } 425 426 if (NULL == pUnknown6BC->swDDICreateDirectDrawObject) 427 { 428 *pNumTextureFormats = D3dDriverData.dwNumTextureFormats; 429 } 430 431 pDriverCaps->DriverCaps9.Caps = HalInfo.ddCaps.dwCaps; 432 pDriverCaps->DriverCaps9.Caps2 = HalInfo.ddCaps.dwCaps2; 433 pDriverCaps->DriverCaps9.Caps3 = HalInfo.ddCaps.dwSVCaps; 434 pDriverCaps->dwSVBCaps = HalInfo.ddCaps.dwSVBCaps; 435 pDriverCaps->dwVSBCaps = HalInfo.ddCaps.dwVSBCaps; 436 pDriverCaps->dwSVBCaps2 = HalInfo.ddCaps.dwSVBCaps2; 437 pUnknown6BC->lDisplayPitch = HalInfo.vmiData.lDisplayPitch; 438 439 if (HalInfo.dwFlags & DDHALINFO_GETDRIVERINFO2) 440 { 441 /* GUID_GetDriverInfo2 - Inform driver of DX version */ 442 { 443 DD_DXVERSION DxVersion; 444 445 ResetGetDriverInfo2Data(&DxVersion.gdi2, D3DGDI2_TYPE_DXVERSION, sizeof(DD_DXVERSION)); 446 DxVersion.dwDXVersion = dwDXVersion; 447 448 PrepareDriverInfoData(&DrvInfo, &DxVersion, sizeof(DxVersion)); 449 OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo); 450 } 451 452 453 /* GUID_GetDriverInfo2 - Get DDI version */ 454 { 455 ResetGetDriverInfo2Data(&DdiVersion.gdi2, D3DGDI2_TYPE_GETDDIVERSION, sizeof(DD_GETDDIVERSIONDATA)); 456 PrepareDriverInfoData(&DrvInfo, &DdiVersion, sizeof(DdiVersion)); 457 bRet = OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo); 458 459 if (DdiVersion.dwDDIVersion != DX9_DDI_VERSION) 460 { 461 DWORD ForceDDIOn; 462 463 ValueSize = sizeof(ForceDDIOn); 464 if (TRUE == ReadRegistryValue(REG_DWORD, "ForceOldDDIOn", (LPBYTE)&ForceDDIOn, &ValueSize) && 465 0 != ForceDDIOn) 466 { 467 DdiVersion.dwDDIVersion = DX9_DDI_VERSION; 468 } 469 } 470 } 471 472 473 /* Check for errors to fallback to DX8 mode */ 474 if (DdiVersion.dwDDIVersion < DX9_DDI_VERSION) 475 { 476 bDX8Mode = TRUE; 477 478 if (DdiVersion.dwDDIVersion == 0) 479 { 480 DPRINT1("Driver claims to be DX9 driver, but didn't report DX9 DDI version - reverting to DX8 mode"); 481 } 482 else 483 { 484 DPRINT1("Driver claims to be DX9 driver, but was built with an old DDI version - reverting to DX8 mode"); 485 } 486 487 /* GUID_GetDriverInfo2 - Get D3DCAPS8 */ 488 { 489 D3DCAPS8 DriverCaps8; 490 491 ResetGetDriverInfo2Data((DD_GETDRIVERINFO2DATA*)&DriverCaps8, D3DGDI2_TYPE_GETD3DCAPS8, sizeof(D3DCAPS8)); 492 PrepareDriverInfoData(&DrvInfo, &DriverCaps8, sizeof(D3DCAPS8)); 493 494 if (FALSE == OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo) || 495 S_OK != DrvInfo.ddRVal || 496 DrvInfo.dwActualSize != sizeof(D3DCAPS8)) 497 { 498 DPRINT1("Driver returned an invalid D3DCAPS8 structure - aborting"); 499 return FALSE; 500 } 501 502 memcpy(&pDriverCaps->DriverCaps9, &DriverCaps8, sizeof(D3DCAPS8)); 503 pDriverCaps->DriverCaps9.Caps = HalInfo.ddCaps.dwCaps; 504 pDriverCaps->dwDriverCaps |= D3D9_INT_D3DCAPS8_VALID; 505 } 506 } 507 508 509 /* GUID_GetDriverInfo2 - Get D3DCAPS9 */ 510 if (FALSE == bDX8Mode) 511 { 512 D3DCAPS9 DriverCaps9; 513 514 ResetGetDriverInfo2Data((DD_GETDRIVERINFO2DATA*)&DriverCaps9, D3DGDI2_TYPE_GETD3DCAPS9, sizeof(D3DCAPS9)); 515 PrepareDriverInfoData(&DrvInfo, &DriverCaps9, sizeof(D3DCAPS9)); 516 517 if (FALSE == OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo) || 518 S_OK != DrvInfo.ddRVal || 519 DrvInfo.dwActualSize != sizeof(D3DCAPS9)) 520 { 521 DPRINT1("Driver returned an invalid D3DCAPS9 structure - aborting"); 522 return FALSE; 523 } 524 525 pDriverCaps->DriverCaps9 = DriverCaps9; 526 pDriverCaps->DriverCaps9.Caps = HalInfo.ddCaps.dwCaps; 527 pDriverCaps->dwDriverCaps |= D3D9_INT_D3DCAPS9_VALID; 528 } 529 530 531 /* GUID_GetDriverInfo2 - Get format count data */ 532 { 533 ResetGetDriverInfo2Data(&FormatCountData.gdi2, D3DGDI2_TYPE_GETFORMATCOUNT, sizeof(DD_GETFORMATCOUNTDATA)); 534 PrepareDriverInfoData(&DrvInfo, &FormatCountData, sizeof(DD_GETFORMATCOUNTDATA)); 535 FormatCountData.dwFormatCount = UINT_MAX; 536 FormatCountData.dwReserved = dwDXVersion; 537 538 if (TRUE == OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo)) 539 { 540 if (DrvInfo.ddRVal != S_OK) 541 { 542 DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI_TYPE_GETFORMATCOUNT in GetDriverInfo call"); 543 return FALSE; 544 } 545 else if (DrvInfo.dwActualSize != sizeof(DD_GETFORMATCOUNTDATA)) 546 { 547 DPRINT1("Driver returned an invalid DD_GETFORMATCOUNTDATA structure - aborting"); 548 return FALSE; 549 } 550 else if (FormatCountData.dwFormatCount == UINT_MAX) 551 { 552 DPRINT1("Driver didn't set DD_GETFORMATCOUNTDATA.dwFormatCount - aborting"); 553 return FALSE; 554 } 555 556 *pNumTextureFormats = FormatCountData.dwFormatCount; 557 } 558 } 559 560 /* GUID_GetDriverInfo2 - Get format data */ 561 if (puD3dTextureFormats != NULL) 562 { 563 DWORD FormatIndex; 564 DD_GETFORMATDATA FormatData; 565 566 for (FormatIndex = 0; FormatIndex < FormatCountData.dwFormatCount; FormatIndex++) 567 { 568 ResetGetDriverInfo2Data(&FormatData.gdi2, D3DGDI2_TYPE_GETFORMAT, sizeof(DD_GETFORMATDATA)); 569 PrepareDriverInfoData(&DrvInfo, &FormatData, sizeof(DD_GETFORMATDATA)); 570 FormatData.dwFormatIndex = FormatIndex; 571 572 if (TRUE == OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo)) 573 { 574 if (DrvInfo.ddRVal != S_OK) 575 { 576 DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI_TYPE_GETFORMAT in GetDriverInfo call"); 577 return FALSE; 578 } 579 else if (DrvInfo.dwActualSize != sizeof(DD_GETFORMATDATA)) 580 { 581 DPRINT1("Driver returned an invalid DD_GETFORMATDATA structure - aborting"); 582 return FALSE; 583 } 584 else if (FormatData.format.dwSize != sizeof(DDPIXELFORMAT)) 585 { 586 DPRINT1("Driver didn't set DD_GETFORMATDATA.format - aborting"); 587 return FALSE; 588 } 589 590 /* Copy format data to puD3dTextureFormats */ 591 memset(puD3dTextureFormats, 0, sizeof(DDSURFACEDESC)); 592 puD3dTextureFormats->dwSize = sizeof(DDSURFACEDESC); 593 puD3dTextureFormats->dwFlags = DDSD_PIXELFORMAT; 594 memcpy(&puD3dTextureFormats->ddpfPixelFormat, &FormatData.format, sizeof(DDPIXELFORMAT)); 595 596 if ((FormatData.format.dwOperations & D3DFORMAT_OP_PIXELSIZE) != 0 && 597 FormatData.format.dwPrivateFormatBitCount > 0) 598 { 599 /* TODO: Register driver's own pixelformat */ 600 } 601 602 ++puD3dTextureFormats; 603 } 604 } 605 } 606 607 /* GUID_GetDriverInfo2 - Get extended mode count data */ 608 { 609 ResetGetDriverInfo2Data(&ExModeCountData.gdi2, D3DGDI2_TYPE_GETEXTENDEDMODECOUNT, sizeof(DD_GETEXTENDEDMODECOUNTDATA)); 610 PrepareDriverInfoData(&DrvInfo, &ExModeCountData, sizeof(DD_GETEXTENDEDMODECOUNTDATA)); 611 ExModeCountData.dwModeCount = UINT_MAX; 612 ExModeCountData.dwReserved = dwDXVersion; 613 614 if (TRUE == OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo)) 615 { 616 if (DrvInfo.ddRVal == S_OK) 617 { 618 if (DrvInfo.dwActualSize != sizeof(DD_GETEXTENDEDMODECOUNTDATA)) 619 { 620 DPRINT1("Driver returned an invalid DD_GETEXTENDEDFORMATCOUNTDATA structure - aborting"); 621 return FALSE; 622 } 623 else if (ExModeCountData.dwModeCount == UINT_MAX) 624 { 625 DPRINT1("Driver didn't set DD_GETEXTENDEDMODECOUNTDATA.dwModeCount - aborting"); 626 return FALSE; 627 } 628 629 *pNumExtendedFormats = ExModeCountData.dwModeCount; 630 } 631 else 632 { 633 ExModeCountData.dwModeCount = 0; 634 } 635 } 636 } 637 638 /* GUID_GetDriverInfo2 - Get extended mode data */ 639 if (pD3dDisplayModeList != NULL) 640 { 641 DWORD ModeIndex; 642 DD_GETEXTENDEDMODEDATA ExModeData; 643 644 for (ModeIndex = 0; ModeIndex < ExModeCountData.dwModeCount; ModeIndex++) 645 { 646 ResetGetDriverInfo2Data(&ExModeData.gdi2, D3DGDI2_TYPE_GETEXTENDEDMODE, sizeof(DD_GETEXTENDEDMODEDATA)); 647 PrepareDriverInfoData(&DrvInfo, &ExModeData, sizeof(DD_GETEXTENDEDMODEDATA)); 648 ExModeData.dwModeIndex = ModeIndex; 649 ExModeData.mode.Width = UINT_MAX; 650 651 if (TRUE == OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo)) 652 { 653 if (DrvInfo.ddRVal != S_OK) 654 { 655 DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI2_TYPE_GETEXTENDEDMODE in GetDriverInfo call"); 656 return FALSE; 657 } 658 else if (DrvInfo.dwActualSize != sizeof(DD_GETEXTENDEDMODEDATA)) 659 { 660 DPRINT1("Driver returned an invalid DD_GETEXTENDEDMODEDATA structure - aborting"); 661 return FALSE; 662 } 663 else if (ExModeData.mode.Width != UINT_MAX) 664 { 665 DPRINT1("Driver didn't set DD_GETEXTENDEDMODEDATA.mode - aborting"); 666 return FALSE; 667 } 668 669 memcpy(pD3dDisplayModeList, &ExModeData.mode, sizeof(D3DDISPLAYMODE)); 670 ++pD3dDisplayModeList; 671 } 672 } 673 } 674 675 /* GUID_GetDriverInfo2 - Get adapter group */ 676 { 677 DD_GETADAPTERGROUPDATA AdapterGroupData; 678 ResetGetDriverInfo2Data(&AdapterGroupData.gdi2, D3DGDI2_TYPE_GETADAPTERGROUP, sizeof(DD_GETADAPTERGROUPDATA)); 679 PrepareDriverInfoData(&DrvInfo, &AdapterGroupData, sizeof(DD_GETADAPTERGROUPDATA)); 680 AdapterGroupData.ulUniqueAdapterGroupId = UINT_MAX; 681 682 if (TRUE == OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo)) 683 { 684 if (DrvInfo.ddRVal != S_OK) 685 { 686 DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI2_TYPE_GETADAPTERGROUP in GetDriverInfo call"); 687 return FALSE; 688 } 689 else if (DrvInfo.dwActualSize != sizeof(DD_GETADAPTERGROUPDATA)) 690 { 691 DPRINT1("Driver returned an invalid DD_GETADAPTERGROUPDATA structure - aborting"); 692 return FALSE; 693 } 694 else if (AdapterGroupData.ulUniqueAdapterGroupId == UINT_MAX) 695 { 696 DPRINT1("Driver didn't set DD_GETADAPTERGROUPDATA.ulUniqueAdapterGroupId - aborting"); 697 return FALSE; 698 } 699 700 pDriverCaps->ulUniqueAdapterGroupId = (ULONG)AdapterGroupData.ulUniqueAdapterGroupId; 701 } 702 } 703 704 /* GUID_GetDriverInfo2 - Query count data */ 705 { 706 ResetGetDriverInfo2Data(&D3dQueryCountData.gdi2, D3DGDI2_TYPE_GETD3DQUERYCOUNT, sizeof(DD_GETD3DQUERYCOUNTDATA)); 707 PrepareDriverInfoData(&DrvInfo, &D3dQueryCountData, sizeof(DD_GETD3DQUERYCOUNTDATA)); 708 D3dQueryCountData.dwNumQueries = UINT_MAX; 709 710 if (TRUE == OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo)) 711 { 712 if (DrvInfo.ddRVal != S_OK) 713 { 714 DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI2_TYPE_GETD3DQUERYCOUNT in GetDriverInfo call"); 715 return FALSE; 716 } 717 else if (DrvInfo.dwActualSize != sizeof(DD_GETD3DQUERYCOUNTDATA)) 718 { 719 DPRINT1("Driver returned an invalid DD_GETD3DQUERYCOUNTDATA structure - aborting"); 720 return FALSE; 721 } 722 else if (D3dQueryCountData.dwNumQueries == UINT_MAX) 723 { 724 DPRINT1("Driver didn't set DD_GETD3DQUERYCOUNTDATA.dwNumQueries - aborting"); 725 return FALSE; 726 } 727 728 *pNumQueries = D3dQueryCountData.dwNumQueries; 729 } 730 } 731 732 /* GUID_GetDriverInfo2 - Query data */ 733 if (pD3dQueryList != NULL) 734 { 735 DWORD QueryIndex; 736 DD_GETD3DQUERYDATA D3dQueryData; 737 738 for (QueryIndex = 0; QueryIndex < D3dQueryCountData.dwNumQueries; QueryIndex++) 739 { 740 ResetGetDriverInfo2Data(&D3dQueryData.gdi2, D3DGDI2_TYPE_GETD3DQUERY, sizeof(DD_GETD3DQUERYDATA)); 741 PrepareDriverInfoData(&DrvInfo, &D3dQueryData, sizeof(DD_GETD3DQUERYDATA)); 742 D3dQueryData.dwQueryIndex = QueryIndex; 743 744 if (TRUE == OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo)) 745 { 746 if (DrvInfo.ddRVal != S_OK) 747 { 748 DPRINT1("Driver claimed to be DX9 driver, but didn't support D3DGDI2_TYPE_GETD3DQUERY in GetDriverInfo call"); 749 return FALSE; 750 } 751 else if (DrvInfo.dwActualSize != sizeof(DD_GETD3DQUERYDATA)) 752 { 753 DPRINT1("Driver returned an invalid DD_GETD3DQUERYDATA structure - aborting"); 754 return FALSE; 755 } 756 757 *pD3dQueryList = D3dQueryData.QueryType; 758 ++pD3dQueryList; 759 } 760 } 761 } 762 } 763 764 /* D3dDriverData -> pGblDriverData */ 765 memcpy(&pGblDriverData->hwCaps, &D3dDriverData.hwCaps, sizeof(D3DNTHALDEVICEDESC_V1)); 766 pGblDriverData->dwNumVertices = D3dDriverData.dwNumVertices; 767 pGblDriverData->dwNumClipVertices = D3dDriverData.dwNumClipVertices; 768 769 /* GUID_D3DExtendedCaps */ 770 { 771 DrvInfo.dwSize = sizeof(DD_GETDRIVERINFODATA); 772 DrvInfo.guidInfo = GUID_D3DExtendedCaps; 773 DrvInfo.dwExpectedSize = sizeof(D3DHAL_D3DEXTENDEDCAPS); 774 DrvInfo.lpvData = pD3dExtendedCaps; 775 bRet = OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo); 776 777 if (TRUE != bRet || DrvInfo.ddRVal != S_OK) 778 { 779 DPRINT1("Driver failed call to GetDriverInfo() with: GUID_D3DExtendedCaps"); 780 return FALSE; 781 } 782 } 783 784 /* GUID_ZPixelFormats */ 785 { 786 DDPIXELFORMAT *pZPixelFormats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FormatCountData.dwFormatCount * sizeof(DDPIXELFORMAT)); 787 788 DrvInfo.dwSize = sizeof(DD_GETDRIVERINFODATA); 789 DrvInfo.guidInfo = GUID_ZPixelFormats; 790 DrvInfo.dwExpectedSize = FormatCountData.dwFormatCount * sizeof(DDPIXELFORMAT); 791 DrvInfo.lpvData = pZPixelFormats; 792 bRet = OsThunkDdGetDriverInfo(pUnknown6BC->hDirectDrawLocal, &DrvInfo); 793 794 if (TRUE != bRet || DrvInfo.ddRVal != S_OK) 795 { 796 DPRINT1("Driver failed call to GetDriverInfo() with: GUID_ZPixelFormats"); 797 HeapFree(GetProcessHeap(), 0, pZPixelFormats); 798 return FALSE; 799 } 800 801 *pNumZStencilFormats = FormatCountData.dwFormatCount; 802 803 if (pD3dZStencilFormatList != NULL) 804 memcpy(pD3dZStencilFormatList, pZPixelFormats, FormatCountData.dwFormatCount * sizeof(DDPIXELFORMAT)); 805 806 HeapFree(GetProcessHeap(), 0, pZPixelFormats); 807 } 808 809 /* Get current display format */ 810 { 811 D3DDISPLAYMODE CurrentDisplayMode; 812 GetAdapterMode(lpszDeviceName, &CurrentDisplayMode); 813 pUnknown6BC->RawDisplayFormat = CurrentDisplayMode.Format; 814 pUnknown6BC->DisplayFormat = CurrentDisplayMode.Format; 815 816 if ((HalInfo.vmiData.ddpfDisplay.dwFlags & DDPF_ALPHAPIXELS) != 0) 817 { 818 if (CurrentDisplayMode.Format == D3DFMT_X8R8G8B8) 819 { 820 pUnknown6BC->DisplayFormat = D3DFMT_A8R8G8B8; 821 } 822 else if (CurrentDisplayMode.Format == D3DFMT_X1R5G5B5) 823 { 824 pUnknown6BC->DisplayFormat = D3DFMT_A1R5G5B5; 825 } 826 } 827 828 pDriverCaps->dwDisplayWidth = CurrentDisplayMode.Width; 829 pDriverCaps->dwDisplayHeight = CurrentDisplayMode.Height; 830 pDriverCaps->RawDisplayFormat = CurrentDisplayMode.Format; 831 pDriverCaps->DisplayFormat = pUnknown6BC->DisplayFormat; 832 pDriverCaps->dwRefreshRate = CurrentDisplayMode.RefreshRate; 833 } 834 835 /* TODO: Set all internal function pointers to create surface, etc. */ 836 pD3D9Callbacks->DdGetAvailDriverMemory = &D3d9GetAvailDriverMemory; 837 838 /* Set device rect */ 839 { 840 HMONITOR hMonitor; 841 MONITORINFO MonitorInfo; 842 843 memset(&MonitorInfo, 0, sizeof(MONITORINFO)); 844 MonitorInfo.cbSize = sizeof(MONITORINFO); 845 846 hMonitor = GetAdapterMonitor(lpszDeviceName); 847 if (TRUE == GetMonitorInfoA(hMonitor, &MonitorInfo)) 848 { 849 pUnknown6BC->DeviceRect = MonitorInfo.rcMonitor; 850 } 851 else 852 { 853 DPRINT1("Could not get monitor information"); 854 } 855 } 856 857 pUnknown6BC->dwCaps = pDriverCaps->DriverCaps9.Caps; 858 pUnknown6BC->dwSVBCaps = pDriverCaps->dwSVBCaps; 859 860 if (FALSE == bDX8Mode) 861 { 862 pUnknown6BC->MajorDxVersion = 9; 863 864 if (0 != (pDriverCaps->DriverCaps9.VertexProcessingCaps & D3DVTXPCAPS_NO_VSDT_UBYTE4)) 865 { 866 DPRINT1("Driver claimed to be DX9 driver, but used depricated D3DCAPS9.VertexProcessingCaps: D3DVTXPCAPS_NO_VSDT_UBYTE4 instead of not setting D3DCAPS9.DeclTypes: D3DDTCAPS_UBYTE4."); 867 return FALSE; 868 } 869 } 870 else 871 { 872 pUnknown6BC->MajorDxVersion = 8; 873 874 if (0 == (pDriverCaps->DriverCaps9.VertexProcessingCaps & D3DVTXPCAPS_NO_VSDT_UBYTE4)) 875 { 876 pDriverCaps->DriverCaps9.DeclTypes |= D3DDTCAPS_UBYTE4; 877 pDriverCaps->DriverCaps9.VertexProcessingCaps &= ~D3DVTXPCAPS_NO_VSDT_UBYTE4; 878 } 879 } 880 881 return TRUE; 882 } 883