[CRT] Massively improve performance of rand_s
[reactos.git] / dll / directx / d3d9 / d3d9_caps.c
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 }