Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygend3d9_create.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/d3d9_create.c 00005 * PURPOSE: d3d9.dll internal create functions and data 00006 * PROGRAMERS: Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se> 00007 */ 00008 00009 #include <d3d9.h> 00010 #include "d3d9_create.h" 00011 #include "d3d9_helpers.h" 00012 #include "d3d9_caps.h" 00013 #include <debug.h> 00014 #include <ddrawi.h> 00015 #include <ddrawgdi.h> 00016 00017 static const GUID DISPLAY_GUID = { 0x67685559, 0x3106, 0x11D0, { 0xB9, 0x71, 0x00, 0xAA, 0x00, 0x34, 0x2F, 0x9F } }; 00018 00019 static CHAR D3D9_PrimaryDeviceName[CCHDEVICENAME]; 00020 00021 static BOOL IsDirectDrawSupported() 00022 { 00023 HDC hDC; 00024 DWORD Planes; 00025 DWORD Bpp; 00026 00027 hDC = GetDC(NULL); 00028 Planes = GetDeviceCaps(hDC, PLANES); 00029 Bpp = GetDeviceCaps(hDC, BITSPIXEL); 00030 ReleaseDC(NULL, hDC); 00031 00032 if (Planes * Bpp < 8) 00033 return FALSE; 00034 00035 return TRUE; 00036 } 00037 00038 static VOID SetAdapterInfo(IN OUT LPDIRECT3D9_DISPLAYADAPTER pDisplayAdapter, IN LPDISPLAY_DEVICEA pDisplayDevice) 00039 { 00040 memcpy(&pDisplayAdapter->DisplayGuid, &DISPLAY_GUID, sizeof(GUID)); 00041 00042 lstrcpynA(pDisplayAdapter->szDeviceName, pDisplayDevice->DeviceName, MAX_PATH); 00043 00044 pDisplayAdapter->dwStateFlags = pDisplayDevice->StateFlags; 00045 pDisplayAdapter->bInUseFlag = TRUE; 00046 } 00047 00048 static BOOL IsGDIDriver(HDC hDC) 00049 { 00050 COLORREF NearestBlack = GetNearestColor(hDC, RGB(0, 0, 0)); 00051 COLORREF NearestWhite = GetNearestColor(hDC, RGB(255, 255, 255)); 00052 00053 if (NearestBlack != RGB(0, 0, 0) || NearestWhite != RGB(255, 255, 255)) 00054 return TRUE; 00055 00056 return FALSE; 00057 } 00058 00059 void GetDisplayAdapterFromDevice(IN OUT LPDIRECT3D9_DISPLAYADAPTER pDisplayAdapters, IN DWORD AdapterIndex, IN LPD3D9_DEVICEDATA pDeviceData) 00060 { 00061 LPDIRECT3D9_DISPLAYADAPTER pDisplayAdapter = &pDisplayAdapters[AdapterIndex]; 00062 DWORD FormatOpIndex; 00063 DWORD AdapterGroupId; 00064 DWORD NumAdaptersInGroup; 00065 DWORD Index; 00066 00067 memcpy(&pDisplayAdapter->DriverCaps, &pDeviceData->DriverCaps, sizeof(D3D9_DRIVERCAPS)); 00068 00069 for (FormatOpIndex = 0; FormatOpIndex < pDeviceData->DriverCaps.NumSupportedFormatOps; FormatOpIndex++) 00070 { 00071 LPDDSURFACEDESC pSurfaceDesc = &pDeviceData->DriverCaps.pSupportedFormatOps[FormatOpIndex]; 00072 D3DFORMAT Format = pSurfaceDesc->ddpfPixelFormat.dwFourCC; 00073 00074 if ((pSurfaceDesc->ddpfPixelFormat.dwOperations & D3DFORMAT_OP_DISPLAYMODE) != 0 && 00075 (Format == D3DFMT_R5G6B5 || Format == D3DFMT_X1R5G5B5)) 00076 { 00077 pDisplayAdapter->Supported16bitFormat = Format; 00078 break; 00079 } 00080 } 00081 00082 NumAdaptersInGroup = 0; 00083 AdapterGroupId = pDeviceData->DriverCaps.ulUniqueAdapterGroupId; 00084 for (Index = 0; Index < AdapterIndex; Index++) 00085 { 00086 if (AdapterGroupId == pDisplayAdapters[Index].DriverCaps.ulUniqueAdapterGroupId) 00087 ++NumAdaptersInGroup; 00088 } 00089 pDisplayAdapter->MasterAdapterIndex = AdapterIndex; 00090 pDisplayAdapter->NumAdaptersInGroup = NumAdaptersInGroup + 1; /* Add self */ 00091 pDisplayAdapter->AdapterIndexInGroup = NumAdaptersInGroup; 00092 00093 CreateDisplayModeList( 00094 pDisplayAdapter->szDeviceName, 00095 NULL, 00096 &pDisplayAdapter->NumSupportedD3DFormats, 00097 pDisplayAdapter->Supported16bitFormat, 00098 pDeviceData->pUnknown6BC 00099 ); 00100 00101 if (pDisplayAdapter->NumSupportedD3DFormats > 0) 00102 { 00103 pDisplayAdapter->pSupportedD3DFormats = HeapAlloc(GetProcessHeap(), 0, pDisplayAdapter->NumSupportedD3DFormats * sizeof(D3DDISPLAYMODE)); 00104 00105 CreateDisplayModeList( 00106 pDisplayAdapter->szDeviceName, 00107 pDisplayAdapter->pSupportedD3DFormats, 00108 &pDisplayAdapter->NumSupportedD3DFormats, 00109 pDisplayAdapter->Supported16bitFormat, 00110 pDeviceData->pUnknown6BC 00111 ); 00112 } 00113 } 00114 00115 BOOL CreateD3D9DeviceData(IN LPDIRECT3D9_DISPLAYADAPTER pDisplayAdapter, IN LPD3D9_DEVICEDATA pDeviceData) 00116 { 00117 HDC hDC; 00118 00119 /* Test DC creation for the display device */ 00120 if (NULL == (hDC = CreateDCA(NULL, pDisplayAdapter->szDeviceName, NULL, NULL))) 00121 { 00122 DPRINT1("Could not create dc for display adapter: %s", pDisplayAdapter->szDeviceName); 00123 return FALSE; 00124 } 00125 00126 pDeviceData->hDC = hDC; 00127 pDeviceData->DisplayGuid = pDisplayAdapter->DisplayGuid; 00128 pDeviceData->DeviceType = D3DDEVTYPE_HAL; 00129 lstrcpynA(pDeviceData->szDeviceName, pDisplayAdapter->szDeviceName, CCHDEVICENAME); 00130 pDeviceData->szDeviceName[CCHDEVICENAME-1] = '\0'; 00131 00132 if (pDisplayAdapter->bInUseFlag) 00133 { 00134 pDeviceData->D3D9Callbacks.DeviceType = D3DDEVTYPE_HAL; 00135 } 00136 else if (IsGDIDriver(hDC)) 00137 { 00138 pDeviceData->D3D9Callbacks.DeviceType = D3DDEVTYPE_REF; 00139 } 00140 00141 if (FALSE == GetDeviceData(pDeviceData)) 00142 { 00143 DPRINT1("Could not get device data for display adapter: %s", pDisplayAdapter->szDeviceName); 00144 return FALSE; 00145 } 00146 00147 return TRUE; 00148 } 00149 00150 VOID DestroyD3D9DeviceData(IN LPD3D9_DEVICEDATA pDeviceData) 00151 { 00152 DeleteDC(pDeviceData->hDC); 00153 HeapFree(GetProcessHeap(), 0, pDeviceData->pUnknown6BC); 00154 } 00155 00156 static BOOL GetDirect3D9AdapterInfo(IN OUT LPDIRECT3D9_DISPLAYADAPTER pDisplayAdapters, IN DWORD AdapterIndex) 00157 { 00158 LPD3D9_DEVICEDATA pDeviceData; 00159 00160 pDeviceData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3D9_DEVICEDATA)); 00161 if (NULL == pDeviceData) 00162 { 00163 DPRINT1("Out of memory, could not initialize Direct3D adapter"); 00164 return FALSE; 00165 } 00166 00167 if (FALSE == CreateD3D9DeviceData(&pDisplayAdapters[AdapterIndex], pDeviceData)) 00168 { 00169 DPRINT1("Could not create device data for adapter: %d", AdapterIndex); 00170 return FALSE; 00171 } 00172 00173 GetDisplayAdapterFromDevice(pDisplayAdapters, AdapterIndex, pDeviceData); 00174 00175 DestroyD3D9DeviceData(pDeviceData); 00176 HeapFree(GetProcessHeap(), 0, pDeviceData); 00177 00178 return TRUE; 00179 } 00180 00181 static BOOL GetDisplayDeviceInfo(IN OUT LPDIRECT3D9_INT pDirect3D9) 00182 { 00183 DISPLAY_DEVICEA DisplayDevice; 00184 DWORD AdapterIndex; 00185 00186 memset(&DisplayDevice, 0, sizeof(DISPLAY_DEVICEA)); 00187 DisplayDevice.cb = sizeof(DISPLAY_DEVICEA); 00188 00189 pDirect3D9->NumDisplayAdapters = 0; 00190 D3D9_PrimaryDeviceName[0] = '\0'; 00191 00192 AdapterIndex = 0; 00193 while (EnumDisplayDevicesA(NULL, AdapterIndex, &DisplayDevice, 0) == TRUE && 00194 pDirect3D9->NumDisplayAdapters < D3D9_INT_MAX_NUM_ADAPTERS) 00195 { 00196 if ((DisplayDevice.StateFlags & (DISPLAY_DEVICE_DISCONNECT | DISPLAY_DEVICE_MIRRORING_DRIVER)) == 0 && 00197 (DisplayDevice.StateFlags & (DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) != 0) 00198 { 00199 SetAdapterInfo(&pDirect3D9->DisplayAdapters[pDirect3D9->NumDisplayAdapters], &DisplayDevice); 00200 00201 if (pDirect3D9->NumDisplayAdapters == 0) 00202 lstrcpynA(D3D9_PrimaryDeviceName, DisplayDevice.DeviceName, sizeof(D3D9_PrimaryDeviceName)); 00203 00204 ++pDirect3D9->NumDisplayAdapters; 00205 break; 00206 } 00207 00208 ++AdapterIndex; 00209 } 00210 00211 AdapterIndex = 0; 00212 while (EnumDisplayDevicesA(NULL, AdapterIndex, &DisplayDevice, 0) == TRUE && 00213 pDirect3D9->NumDisplayAdapters < D3D9_INT_MAX_NUM_ADAPTERS) 00214 { 00215 if ((DisplayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0 && 00216 (DisplayDevice.StateFlags & (DISPLAY_DEVICE_MIRRORING_DRIVER | DISPLAY_DEVICE_PRIMARY_DEVICE)) == 0) 00217 { 00218 SetAdapterInfo(&pDirect3D9->DisplayAdapters[pDirect3D9->NumDisplayAdapters], &DisplayDevice); 00219 ++pDirect3D9->NumDisplayAdapters; 00220 } 00221 00222 ++AdapterIndex; 00223 } 00224 00225 /* Check if minimum DirectDraw is supported */ 00226 if (IsDirectDrawSupported() == FALSE) 00227 return FALSE; 00228 00229 for (AdapterIndex = 0; AdapterIndex < pDirect3D9->NumDisplayAdapters; AdapterIndex++) 00230 { 00231 GetDirect3D9AdapterInfo(pDirect3D9->DisplayAdapters, AdapterIndex); 00232 } 00233 00234 return TRUE; 00235 } 00236 00237 HRESULT CreateD3D9(OUT LPDIRECT3D9 *ppDirect3D9, UINT SDKVersion) 00238 { 00239 LPDIRECT3D9_INT pDirect3D9; 00240 00241 if (ppDirect3D9 == 0) 00242 return DDERR_INVALIDPARAMS; 00243 00244 if (AlignedAlloc((LPVOID *)&pDirect3D9, sizeof(DIRECT3D9_INT)) != S_OK) 00245 return DDERR_OUTOFMEMORY; 00246 00247 if (pDirect3D9 == 0) 00248 return DDERR_OUTOFMEMORY; 00249 00250 pDirect3D9->lpVtbl = &Direct3D9_Vtbl; 00251 pDirect3D9->dwProcessId = GetCurrentThreadId(); 00252 pDirect3D9->lRefCnt = 1; 00253 00254 pDirect3D9->SDKVersion = SDKVersion; 00255 00256 pDirect3D9->lpInt = pDirect3D9; 00257 pDirect3D9->unknown000007 = 1; 00258 00259 InitializeCriticalSection(&pDirect3D9->d3d9_cs); 00260 00261 if (FALSE == GetDisplayDeviceInfo(pDirect3D9)) 00262 { 00263 DPRINT1("Could not create Direct3D9 object"); 00264 AlignedFree(pDirect3D9); 00265 return DDERR_GENERIC; 00266 } 00267 00268 *ppDirect3D9 = (LPDIRECT3D9)&pDirect3D9->lpVtbl; 00269 00270 return D3D_OK; 00271 } 00272 Generated on Sun May 27 2012 04:21:13 for ReactOS by
1.7.6.1
|