ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

adapter.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS ReactX
00004  * FILE:            dll/directx/d3d9/adapter.c
00005  * PURPOSE:         d3d9.dll adapter info functions
00006  * PROGRAMERS:      Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se>
00007  */
00008 
00009 #include "d3d9_common.h"
00010 #include <d3d9.h>
00011 #include <ddraw.h>
00012 #include <debug.h>
00013 #include <d3dhal.h>
00014 #include "d3d9_private.h"
00015 #include "d3d9_helpers.h"
00016 #include "adapter.h"
00017 
00018 #define D3D9_CAPS1              (D3DCAPS_READ_SCANLINE)
00019 #define D3D9_PRE_XP_CAPS2       (D3DCAPS2_CANAUTOGENMIPMAP | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_RESERVED | D3DCAPS2_FULLSCREENGAMMA)
00020 #define D3D9_XP_OR_LATER_CAPS2  (D3D9_PRE_XP_CAPS2 | D3DCAPS2_CANMANAGERESOURCE)
00021 #define D3D9_CAPS3              (D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD | D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION | D3DCAPS3_COPY_TO_VIDMEM | D3DCAPS3_COPY_TO_SYSTEMMEM)
00022 #define D3D9_DEVCAPS            (D3DDEVCAPS_EXECUTESYSTEMMEMORY | D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY \
00023                                 | D3DDEVCAPS_TLVERTEXVIDEOMEMORY | D3DDEVCAPS_TEXTURESYSTEMMEMORY | D3DDEVCAPS_TEXTUREVIDEOMEMORY \
00024                                 | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_TEXTURENONLOCALVIDMEM \
00025                                 | D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_SEPARATETEXTUREMEMORIES | D3DDEVCAPS_DRAWPRIMITIVES2EX \
00026                                 | D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_CANBLTSYSTONONLOCAL | D3DDEVCAPS_HWRASTERIZATION \
00027                                 | D3DDEVCAPS_PUREDEVICE | D3DDEVCAPS_QUINTICRTPATCHES | D3DDEVCAPS_RTPATCHES | D3DDEVCAPS_RTPATCHHANDLEZERO \
00028                                 | D3DDEVCAPS_NPATCHES)
00029 
00030 #define D3DCAPS2_PRESENT_INTERVAL_SEVERAL       0x00200000
00031 #define D3DCAPS2_PRESENT_INTERVAL_IMMEDIATE     0x00400000
00032 
00033 #define D3DVTXPCAPS_FOGVERTEX                   0x00000004
00034 
00035 typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
00036 typedef BOOL (WINAPI *LPFN_DISABLEWOW64FSREDIRECTION) (PVOID*);
00037 typedef BOOL (WINAPI *LPFN_REVERTWOW64FSREDIRECTION) (PVOID);
00038 
00039 
00040 typedef struct _ADAPTERMONITOR
00041 {
00042     LPCSTR lpszDeviceName;
00043     HMONITOR hMonitor;
00044 } ADAPTERMONITOR, *LPADAPTERMONITOR;
00045 
00046 
00047 static BOOL GetDriverName(LPDISPLAY_DEVICEA pDisplayDevice, D3DADAPTER_IDENTIFIER9* pIdentifier)
00048 {
00049     HKEY hKey;
00050     BOOL bResult = FALSE;
00051 
00052     if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_LOCAL_MACHINE, pDisplayDevice->DeviceKey + strlen("\\Registry\\Machine\\"), 0, KEY_QUERY_VALUE, &hKey))
00053     {
00054         DWORD DriverNameLength = MAX_DEVICE_IDENTIFIER_STRING - (DWORD)strlen(".dll");
00055         DWORD Type = 0;
00056 
00057         if (ERROR_SUCCESS == RegQueryValueExA(hKey, "InstalledDisplayDrivers", 0, &Type, (LPBYTE)pIdentifier->Driver, &DriverNameLength))
00058         {
00059             pIdentifier->Driver[DriverNameLength] = '\0';
00060             SafeAppendString(pIdentifier->Driver, MAX_DEVICE_IDENTIFIER_STRING, ".dll");
00061             bResult = TRUE;
00062         }
00063 
00064         RegCloseKey(hKey);
00065     }
00066 
00067     return bResult;
00068 }
00069 
00070 static void GetDriverVersion(LPDISPLAY_DEVICEA pDisplayDevice, D3DADAPTER_IDENTIFIER9* pIdentifier)
00071 {
00072     HMODULE hModule;
00073     LPFN_ISWOW64PROCESS fnIsWow64Process;
00074     BOOL bIsWow64 = FALSE;
00075     PVOID OldWow64RedirectValue;
00076     UINT DriverFileSize;
00077 
00078     hModule = GetModuleHandleA("KERNEL32");
00079     fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(hModule, "IsWow64Process");
00080     if (fnIsWow64Process)
00081     {
00082         fnIsWow64Process(GetCurrentProcess(), &bIsWow64);
00083         if (bIsWow64)
00084         {
00085             LPFN_DISABLEWOW64FSREDIRECTION fnDisableWow64FsRedirection;
00086             fnDisableWow64FsRedirection = (LPFN_DISABLEWOW64FSREDIRECTION)GetProcAddress(hModule, "Wow64DisableWow64FsRedirection");
00087             fnDisableWow64FsRedirection(&OldWow64RedirectValue);
00088         }
00089     }
00090 
00091     DriverFileSize = GetFileVersionInfoSizeA(pIdentifier->Driver, NULL);
00092     if (DriverFileSize > 0)
00093     {
00094         VS_FIXEDFILEINFO* FixedFileInfo = NULL;
00095         LPVOID pBlock = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DriverFileSize);
00096 
00097         if (TRUE == GetFileVersionInfoA(pIdentifier->Driver, 0, DriverFileSize, pBlock))
00098         {
00099             if (TRUE == VerQueryValueA(pBlock, "\\", (LPVOID*)&FixedFileInfo, &DriverFileSize))
00100             {
00101                 pIdentifier->DriverVersion.HighPart = FixedFileInfo->dwFileVersionMS;
00102                 pIdentifier->DriverVersion.LowPart = FixedFileInfo->dwFileVersionLS;
00103             }
00104         }
00105 
00106         HeapFree(GetProcessHeap(), 0, pBlock);
00107     }
00108 
00109     if (bIsWow64)
00110     {
00111         LPFN_REVERTWOW64FSREDIRECTION fnRevertWow64FsRedirection;
00112         fnRevertWow64FsRedirection = (LPFN_REVERTWOW64FSREDIRECTION)GetProcAddress(hModule, "Wow64RevertWow64FsRedirection");
00113         fnRevertWow64FsRedirection(&OldWow64RedirectValue);
00114     }
00115 }
00116 
00117 
00118 static void ParseField(LPCSTR lpszDeviceKey, LPDWORD pField, LPCSTR lpszSubString)
00119 {
00120     const char* ResultStr;
00121     ResultStr = strstr(lpszDeviceKey, lpszSubString);
00122     if (ResultStr != NULL)
00123     {
00124         *pField = strtol(ResultStr + strlen(lpszSubString), NULL, 16);
00125     }
00126 }
00127 
00128 static void GetDeviceId(LPCSTR lpszDeviceKey, D3DADAPTER_IDENTIFIER9* pIdentifier)
00129 {
00130     ParseField(lpszDeviceKey, &pIdentifier->VendorId, "VEN_");
00131     ParseField(lpszDeviceKey, &pIdentifier->DeviceId, "DEV_");
00132     ParseField(lpszDeviceKey, &pIdentifier->SubSysId, "SUBSYS_");
00133     ParseField(lpszDeviceKey, &pIdentifier->Revision, "REV_");
00134 }
00135 
00136 static void GenerateDeviceIdentifier(D3DADAPTER_IDENTIFIER9* pIdentifier)
00137 {
00138     DWORD* dwIdentifier = (DWORD*)&pIdentifier->DeviceIdentifier;
00139 
00140     pIdentifier->DeviceIdentifier = CLSID_DirectDraw;
00141 
00142     dwIdentifier[0] ^= pIdentifier->VendorId;
00143     dwIdentifier[1] ^= pIdentifier->DeviceId;
00144     dwIdentifier[2] ^= pIdentifier->SubSysId;
00145     dwIdentifier[3] ^= pIdentifier->Revision;
00146     dwIdentifier[2] ^= pIdentifier->DriverVersion.LowPart;
00147     dwIdentifier[3] ^= pIdentifier->DriverVersion.HighPart;
00148 }
00149 
00150 BOOL GetAdapterInfo(LPCSTR lpszDeviceName, D3DADAPTER_IDENTIFIER9* pIdentifier)
00151 {
00152     DISPLAY_DEVICEA DisplayDevice;
00153     DWORD AdapterIndex;
00154     BOOL FoundDisplayDevice;
00155 
00156     memset(&DisplayDevice, 0, sizeof(DISPLAY_DEVICEA));
00157     DisplayDevice.cb = sizeof(DISPLAY_DEVICEA);   
00158 
00159     AdapterIndex = 0;
00160     FoundDisplayDevice = FALSE;
00161     while (EnumDisplayDevicesA(NULL, AdapterIndex, &DisplayDevice, 0) == TRUE)
00162     {
00163         if (_stricmp(lpszDeviceName, DisplayDevice.DeviceName) == 0)
00164         {
00165             FoundDisplayDevice = TRUE;
00166             break;
00167         }
00168 
00169         ++AdapterIndex;
00170     }
00171 
00172     /* No matching display device found? */
00173     if (FALSE == FoundDisplayDevice)
00174         return FALSE;
00175 
00176     lstrcpynA(pIdentifier->Description, DisplayDevice.DeviceString, MAX_DEVICE_IDENTIFIER_STRING);
00177     lstrcpynA(pIdentifier->DeviceName, DisplayDevice.DeviceName, CCHDEVICENAME);
00178 
00179     if (GetDriverName(&DisplayDevice, pIdentifier) == TRUE)
00180         GetDriverVersion(&DisplayDevice, pIdentifier);
00181 
00182     GetDeviceId(DisplayDevice.DeviceID, pIdentifier);
00183 
00184     GenerateDeviceIdentifier(pIdentifier);
00185 
00186     return TRUE;
00187 }
00188 
00189 
00190 
00191 static BOOL IsWindowsXPorLaterCompatible()
00192 {
00193     OSVERSIONINFOA osvi;
00194 
00195     ZeroMemory(&osvi, sizeof(OSVERSIONINFOA));
00196     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
00197 
00198     if (GetVersionExA(&osvi) != 0)
00199     {
00200         return ( (osvi.dwMajorVersion > 5) ||
00201                ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ));
00202     }
00203 
00204     return FALSE;
00205 }
00206 
00207 static void CopyDriverCaps(const D3DCAPS9* pSrcCaps, D3DCAPS9* pDstCaps)
00208 {
00209     *pDstCaps = *pSrcCaps;
00210 
00211     pDstCaps->Caps = pSrcCaps->Caps & D3D9_CAPS1;
00212 
00213     /* TODO: Fit in D3DCAPS2_CANCALIBRATEGAMMA somewhere here */
00214     if (IsWindowsXPorLaterCompatible())
00215         pDstCaps->Caps2 = pSrcCaps->Caps2 & D3D9_XP_OR_LATER_CAPS2;
00216     else
00217         pDstCaps->Caps2 = pSrcCaps->Caps2 & D3D9_PRE_XP_CAPS2;
00218 
00219     pDstCaps->Caps3 = pSrcCaps->Caps3 & D3D9_CAPS3;
00220     pDstCaps->DevCaps = pSrcCaps->DevCaps & D3D9_DEVCAPS;
00221 
00222     pDstCaps->PresentationIntervals = D3DPRESENT_INTERVAL_ONE;
00223     if (pSrcCaps->Caps2 & D3DCAPS2_PRESENT_INTERVAL_SEVERAL)
00224         pDstCaps->PresentationIntervals |= (D3DPRESENT_INTERVAL_TWO | D3DPRESENT_INTERVAL_THREE | D3DPRESENT_INTERVAL_FOUR);
00225     if (pSrcCaps->Caps2 & D3DCAPS2_PRESENT_INTERVAL_IMMEDIATE)
00226         pDstCaps->PresentationIntervals |= D3DPRESENT_INTERVAL_IMMEDIATE;
00227 
00228     pDstCaps->PrimitiveMiscCaps = pSrcCaps->PrimitiveMiscCaps & ~D3DPMISCCAPS_FOGINFVF;
00229 
00230     if (pSrcCaps->VertexProcessingCaps & D3DVTXPCAPS_FOGVERTEX)
00231     {
00232         pDstCaps->RasterCaps |= D3DPRASTERCAPS_FOGVERTEX;
00233         pDstCaps->VertexProcessingCaps &= ~D3DVTXPCAPS_FOGVERTEX;
00234     }
00235 
00236     if (pSrcCaps->MaxPointSize < 0.0f)
00237         pDstCaps->MaxPointSize = 1.0f;
00238 }
00239 
00240 HRESULT GetAdapterCaps(const LPDIRECT3D9_DISPLAYADAPTER pDisplayAdapter, D3DDEVTYPE DeviceType, D3DCAPS9* pDstCaps)
00241 {
00242     HRESULT hResult = D3DERR_INVALIDDEVICE;
00243     D3DCAPS9* pDriverCaps = NULL;
00244 
00245     ZeroMemory(pDstCaps, sizeof(D3DCAPS9));
00246 
00247     switch (DeviceType)
00248     {
00249     case D3DDEVTYPE_HAL:
00250         pDriverCaps = &pDisplayAdapter->DriverCaps.DriverCaps9;
00251         hResult = D3D_OK;
00252         break;
00253 
00254     case D3DDEVTYPE_REF:
00255     case D3DDEVTYPE_SW:
00256     case D3DDEVTYPE_NULLREF:
00257         UNIMPLEMENTED;
00258         hResult = D3D_OK;
00259         break;
00260 
00261     default:
00262         DPRINT1("Unknown DeviceType argument");
00263         break;
00264     }
00265 
00266     if (pDriverCaps != NULL)
00267     {
00268         CopyDriverCaps(pDriverCaps, pDstCaps);
00269     }
00270 
00271     if (SUCCEEDED(hResult))
00272     {
00273         pDstCaps->DeviceType = DeviceType;
00274         pDstCaps->MasterAdapterOrdinal = pDisplayAdapter->MasterAdapterIndex;
00275         pDstCaps->AdapterOrdinalInGroup = pDisplayAdapter->AdapterIndexInGroup;
00276         pDstCaps->NumberOfAdaptersInGroup = pDisplayAdapter->NumAdaptersInGroup;
00277     }
00278 
00279     return hResult;
00280 }
00281 
00282 
00283 
00284 static D3DFORMAT Get16BitD3DFormat(LPCSTR lpszDeviceName)
00285 {
00286     HDC hDC;
00287     HBITMAP hBitmap;
00288     LPBITMAPINFO pBitmapInfo;
00289     D3DFORMAT Format = D3DFMT_R5G6B5;
00290 
00291     if (NULL == (hDC = CreateDCA(NULL, lpszDeviceName, NULL, NULL)))
00292     {
00293         return Format;
00294     }
00295 
00296     if (NULL == (hBitmap = CreateCompatibleBitmap(hDC, 1, 1)))
00297     {
00298         DeleteDC(hDC);
00299         return Format;
00300     }
00301 
00302     pBitmapInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 4 * sizeof(RGBQUAD));
00303     if (NULL == pBitmapInfo)
00304     {
00305         DeleteObject(hBitmap);
00306         DeleteDC(hDC);
00307         return Format;
00308     }
00309 
00310     pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00311     if (GetDIBits(hDC, hBitmap, 0, 0, NULL, pBitmapInfo, DIB_RGB_COLORS) > 0)
00312     {
00313         if (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS)
00314         {
00315             if (GetDIBits(hDC, hBitmap, 0, pBitmapInfo->bmiHeader.biHeight, NULL, pBitmapInfo, DIB_RGB_COLORS) > 0)
00316             {
00317                 /* Check if the green field is 6 bits long */
00318                 if (*(DWORD*)(&pBitmapInfo->bmiColors[1]) == 0x000003E0)
00319                 {
00320                     Format = D3DFMT_X1R5G5B5;
00321                 }
00322             }
00323         }
00324     }
00325 
00326     HeapFree(GetProcessHeap(), 0, pBitmapInfo);
00327     DeleteObject(hBitmap);
00328     DeleteDC(hDC);
00329 
00330     return Format;
00331 }
00332 
00333 BOOL GetAdapterMode(LPCSTR lpszDeviceName, D3DDISPLAYMODE* pMode)
00334 {
00335     DEVMODEA DevMode;
00336     
00337     memset(&DevMode, 0, sizeof(DEVMODEA));
00338     DevMode.dmSize = sizeof(DEVMODEA);
00339     if (FALSE == EnumDisplaySettingsA(lpszDeviceName, ENUM_CURRENT_SETTINGS, &DevMode))
00340         return FALSE;
00341 
00342     pMode->Width = DevMode.dmPelsWidth;
00343     pMode->Height = DevMode.dmPelsHeight;
00344     pMode->RefreshRate = DevMode.dmDisplayFrequency;
00345     
00346     switch (DevMode.dmBitsPerPel)
00347     {
00348     case 8:
00349         pMode->Format = D3DFMT_P8;
00350         break;
00351 
00352     case 16:
00353         pMode->Format = Get16BitD3DFormat(lpszDeviceName);
00354         break;
00355 
00356     case 24:
00357         pMode->Format = D3DFMT_R8G8B8;
00358         break;
00359 
00360     case 32:
00361         pMode->Format = D3DFMT_X8R8G8B8;
00362         break;
00363 
00364     default:
00365         pMode->Format = D3DFMT_UNKNOWN;
00366         break;
00367     }
00368 
00369     return TRUE;
00370 }
00371 
00372 
00373 
00374 static BOOL CALLBACK AdapterMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
00375 {
00376     MONITORINFOEXA MonitorInfoEx;
00377     LPADAPTERMONITOR lpAdapterMonitor = (LPADAPTERMONITOR)dwData;
00378 
00379     memset(&MonitorInfoEx, 0, sizeof(MONITORINFOEXA));
00380     MonitorInfoEx.cbSize = sizeof(MONITORINFOEXA);
00381 
00382     GetMonitorInfoA(hMonitor, (LPMONITORINFO)&MonitorInfoEx);
00383 
00384     if (_stricmp(lpAdapterMonitor->lpszDeviceName, MonitorInfoEx.szDevice) == 0)
00385     {
00386         lpAdapterMonitor->hMonitor = hMonitor;
00387         return FALSE;
00388     }
00389 
00390     return TRUE;
00391 }
00392 
00393 HMONITOR GetAdapterMonitor(LPCSTR lpszDeviceName)
00394 {
00395     ADAPTERMONITOR AdapterMonitor;
00396     AdapterMonitor.lpszDeviceName = lpszDeviceName;
00397     AdapterMonitor.hMonitor = NULL;
00398 
00399     EnumDisplayMonitors(NULL, NULL, AdapterMonitorEnumProc, (LPARAM)&AdapterMonitor);
00400 
00401     return AdapterMonitor.hMonitor;
00402 }
00403 
00404 
00405 
00406 UINT GetDisplayFormatCount(D3DFORMAT Format, const D3DDISPLAYMODE* pSupportedDisplayModes, UINT NumDisplayModes)
00407 {
00408     UINT DisplayModeIndex;
00409     UINT FormatIndex = 0;
00410 
00411     for (DisplayModeIndex = 0; DisplayModeIndex < NumDisplayModes; DisplayModeIndex++)
00412     {
00413         if (pSupportedDisplayModes[DisplayModeIndex].Format == Format)
00414         {
00415             ++FormatIndex;
00416         }
00417     }
00418 
00419     return FormatIndex;
00420 }
00421 
00422 const D3DDISPLAYMODE* FindDisplayFormat(D3DFORMAT Format, UINT ModeIndex, const D3DDISPLAYMODE* pSupportedDisplayModes, UINT NumDisplayModes)
00423 {
00424     UINT DisplayModeIndex;
00425     UINT FormatIndex = 0;
00426 
00427     for (DisplayModeIndex = 0; DisplayModeIndex < NumDisplayModes; DisplayModeIndex++)
00428     {
00429         if (pSupportedDisplayModes[DisplayModeIndex].Format == Format)
00430         {
00431             if (ModeIndex == FormatIndex)
00432                 return &pSupportedDisplayModes[DisplayModeIndex];
00433 
00434             ++FormatIndex;
00435         }
00436     }
00437 
00438     if (FormatIndex == 0)
00439     {
00440         DPRINT1("No modes with the specified format found");
00441     }
00442     else if (FormatIndex < ModeIndex)
00443     {
00444         DPRINT1("Invalid mode index");
00445     }
00446 
00447     return NULL;
00448 }

Generated on Sun May 27 2012 04:21:13 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.