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