diff --git a/reactos/dll/directx/d3d9/adapter.c b/reactos/dll/directx/d3d9/adapter.c index 0eee942a7ba..0cb936976c2 100644 --- a/reactos/dll/directx/d3d9/adapter.c +++ b/reactos/dll/directx/d3d9/adapter.c @@ -86,7 +86,7 @@ static void GetDriverVersion(LPDISPLAY_DEVICEA pDisplayDevice, D3DADAPTER_IDENTI if (DriverFileSize > 0) { VS_FIXEDFILEINFO* FixedFileInfo = NULL; - LPVOID pBlock = LocalAlloc(LMEM_ZEROINIT, DriverFileSize); + LPVOID pBlock = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DriverFileSize); if (TRUE == GetFileVersionInfoA(pIdentifier->Driver, 0, DriverFileSize, pBlock)) { @@ -97,7 +97,7 @@ static void GetDriverVersion(LPDISPLAY_DEVICEA pDisplayDevice, D3DADAPTER_IDENTI } } - LocalFree(pBlock); + HeapFree(GetProcessHeap(), 0, pBlock); } if (bIsWow64) @@ -292,7 +292,7 @@ static D3DFORMAT Get16BitD3DFormat(LPCSTR lpszDeviceName) return Format; } - pBitmapInfo = LocalAlloc(LMEM_ZEROINIT, sizeof(BITMAPINFOHEADER) + 4 * sizeof(RGBQUAD)); + pBitmapInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 4 * sizeof(RGBQUAD)); if (NULL == pBitmapInfo) { DeleteObject(hBitmap); @@ -316,7 +316,7 @@ static D3DFORMAT Get16BitD3DFormat(LPCSTR lpszDeviceName) } } - LocalFree(pBitmapInfo); + HeapFree(GetProcessHeap(), 0, pBitmapInfo); DeleteObject(hBitmap); DeleteDC(hDC); diff --git a/reactos/dll/directx/d3d9/d3d9_create.c b/reactos/dll/directx/d3d9/d3d9_create.c index bbad296c554..9e10f5932a2 100644 --- a/reactos/dll/directx/d3d9/d3d9_create.c +++ b/reactos/dll/directx/d3d9/d3d9_create.c @@ -65,7 +65,7 @@ static BOOL GetDirect3DAdapterInfo(IN OUT LPDIRECT3D9_DISPLAYADAPTER_INT pDispla if (NULL == (hDC = CreateDCA(NULL, pDisplayAdapter->szDeviceName, NULL, NULL))) return FALSE; - pDeviceData = LocalAlloc(LMEM_ZEROINIT, sizeof(D3D9_DEVICEDATA)); + pDeviceData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3D9_DEVICEDATA)); if (NULL == pDeviceData) { DPRINT1("Out of memory, could not initialize Direct3D adapter"); diff --git a/reactos/dll/directx/d3d9/d3d9_helpers.c b/reactos/dll/directx/d3d9/d3d9_helpers.c index fdc69793f47..676631aae55 100644 --- a/reactos/dll/directx/d3d9/d3d9_helpers.c +++ b/reactos/dll/directx/d3d9/d3d9_helpers.c @@ -64,7 +64,7 @@ HRESULT AlignedAlloc(IN OUT LPVOID *ppObject, IN SIZE_T dwSize) dwSize += MEM_ALIGNMENT; - AlignedPtr = (CHAR *)LocalAlloc(LMEM_ZEROINIT, dwSize); + AlignedPtr = (CHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); if (AlignedPtr == 0) return DDERR_OUTOFMEMORY; @@ -91,5 +91,5 @@ VOID AlignedFree(IN OUT LPVOID pObject) NonAlignedPtr -= *(AlignedPtr - 1); - LocalFree(NonAlignedPtr); + HeapFree(GetProcessHeap(), 0, NonAlignedPtr); } diff --git a/reactos/dll/directx/d3d9/d3d9_impl.c b/reactos/dll/directx/d3d9/d3d9_impl.c index 338b506ace4..a86c08b20e4 100644 --- a/reactos/dll/directx/d3d9/d3d9_impl.c +++ b/reactos/dll/directx/d3d9/d3d9_impl.c @@ -640,12 +640,79 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDepthStencilMatch(LPDIRECT3D9 iface, U return D3D_OK; } + +/*++ +* @name IDirect3D9::CheckDeviceFormatConversion +* @implemented +* +* The function IDirect3D9Impl_CheckDeviceFormatConversion checks if a specific D3DFORMAT +* can be converted to another on the specified display adapter. +* +* @param LPDIRECT3D iface +* Pointer to the IDirect3D object returned from Direct3DCreate9() +* +* @param UINT Adapter +* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. +* The maximum value for this is the value returned by IDirect3D::GetAdapterCount(). +* +* @param D3DDEVTYPE DeviceType +* One of the D3DDEVTYPE enum members. Only D3DDEVTYPE_HAL can potentially return D3D_OK. +* +* @param D3DFORMAT SourceFormat +* One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode to be converted from. +* +* @param D3DFORMAT TargetFormat +* One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode to be converted to. +* +* @return HRESULT +* If the SourceFormat can be converted to the TargetFormat, the method returns D3D_OK. +* If the SourceFormat can NOT be converted to the TargetFormat, the method returns D3DERR_NOTAVAILABLE. +* If Adapter is out of range, DeviceType is invalid, +* SourceFormat or TargetFormat is invalid, the method returns D3DERR_INVALIDCALL. +* +*/ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormatConversion(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) { - UNIMPLEMENTED + HRESULT hResult; + LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface); + LOCK_D3D9(); - return D3D_OK; + if (Adapter >= This->NumDisplayAdapters) + { + DPRINT1("Invalid Adapter number specified"); + UNLOCK_D3D9(); + return D3DERR_INVALIDCALL; + } + + if (DeviceType != D3DDEVTYPE_HAL && + DeviceType != D3DDEVTYPE_REF && + DeviceType != D3DDEVTYPE_SW) + { + DPRINT1("Invalid DeviceType specified"); + UNLOCK_D3D9(); + return D3DERR_INVALIDCALL; + } + + if (SourceFormat == D3DFMT_UNKNOWN || + TargetFormat == D3DFMT_UNKNOWN) + { + DPRINT1("Invalid D3DFORMAT specified"); + UNLOCK_D3D9(); + return D3DERR_NOTAVAILABLE; + } + + if (DeviceType == D3DDEVTYPE_HAL) + { + hResult = CheckDeviceFormatConversion(&This->DisplayAdapters[Adapter].DriverCaps, SourceFormat, TargetFormat); + } + else + { + hResult = D3DERR_NOTAVAILABLE; + } + + UNLOCK_D3D9(); + return hResult; } diff --git a/reactos/dll/directx/d3d9/d3d9_private.h b/reactos/dll/directx/d3d9/d3d9_private.h index 60b914ac29b..63c5407233f 100644 --- a/reactos/dll/directx/d3d9/d3d9_private.h +++ b/reactos/dll/directx/d3d9/d3d9_private.h @@ -89,7 +89,7 @@ typedef struct _tagD3D9_DEVICEDATA /* 0x0220 */ CHAR szDeviceName[CCHDEVICENAME]; /* 0x0240 */ HDC hDC; /* 0x0244 */ GUID DisplayGuid; -/* 0x0254 */ LPDWORD pUnknown0254; //D3D9_Unknown6BC_INT* pUnknown6BC; // hDirectDrawLocal +/* 0x0254 */ LPDWORD pUnknown0254; //D3D9_Unknown6BC_INT* pUnknown6BC; /* 0x0258 */ D3DDEVTYPE DeviceType; /* 0x025c */ HMODULE hD3DRefDll; /* 0x0260 */ DWORD unknown0152; @@ -103,7 +103,7 @@ typedef struct _tagDIRECT3D9DisplayAdapterInfo_ /* 0x0118 */ BOOL bInUseFlag; /* 0x011c */ DWORD MasterAdapterIndex; /* 0x0120 */ DWORD AdapterIndexInGroup; -/* 0x0124 */ DWORD NumAdaptersInGroup; /* 0x00000001 */ +/* 0x0124 */ DWORD NumAdaptersInGroup; /* 0x0128 */ DWORD NumSupportedD3DFormats; /* 0x012c */ DWORD NumSupportedD3DExtendedFormats; /* 0x0130 */ D3DDISPLAYMODE* pSupportedD3DFormats; @@ -116,7 +116,7 @@ typedef struct _tagDIRECT3D9DisplayAdapterInfo_ typedef struct _tagDIRECT3D9_INT_ { -/* 0x0000 */ struct IDirect3D9Vtbl *lpVtbl; /* LPDIRECTD3D9 functoions table */ +/* 0x0000 */ struct IDirect3D9Vtbl *lpVtbl; /* LPDIRECTD3D9 function table */ /* 0x0004 */ CRITICAL_SECTION d3d9_cs; /* 0x001c */ DWORD unknown000007; /* 0x00000001 */ /* 0x0020 */ DWORD dwProcessId; diff --git a/reactos/dll/directx/d3d9/format.c b/reactos/dll/directx/d3d9/format.c index cd943971899..c6041a79198 100644 --- a/reactos/dll/directx/d3d9/format.c +++ b/reactos/dll/directx/d3d9/format.c @@ -33,6 +33,20 @@ BOOL IsMultiElementFormat(D3DFORMAT Format) return (Format == D3DFMT_MULTI2_ARGB8); } +BOOL IsFourCCFormat(D3DFORMAT Format) +{ + CHAR* cFormat = (CHAR*)&Format; + if (isalnum(cFormat[0]) && + isalnum(cFormat[1]) && + isalnum(cFormat[2]) && + isalnum(cFormat[3])) + { + return TRUE; + } + + return FALSE; +} + BOOL IsSupportedFormatOp(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT DisplayFormat, DWORD FormatOp) { const DWORD NumFormatOps = pDriverCaps->NumSupportedFormatOps; @@ -321,3 +335,47 @@ HRESULT CheckDeviceFormat(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT AdapterFormat return D3DERR_NOTAVAILABLE; } + +HRESULT CheckDeviceFormatConversion(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) +{ + D3DFORMAT NonAlphaSourceFormat; + D3DFORMAT NonAlphaTargetFormat; + + NonAlphaSourceFormat = RemoveAlphaChannel(SourceFormat); + NonAlphaTargetFormat = RemoveAlphaChannel(TargetFormat); + + if (NonAlphaSourceFormat == NonAlphaTargetFormat) + { + return D3D_OK; + } + + if (FALSE == IsFourCCFormat(SourceFormat)) + { + switch (SourceFormat) + { + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + case D3DFMT_R5G6B5: + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + case D3DFMT_A2R10G10B10: + /* Do nothing, valid SourceFormat */ + break; + + default: + return D3DERR_NOTAVAILABLE; + } + } + else if (pDriverCaps->DriverCaps9.DevCaps2 == 0) + { + return D3D_OK; + } + + if (FALSE == IsSupportedFormatOp(pDriverCaps, SourceFormat, D3DFORMAT_OP_CONVERT_TO_ARGB) || + FALSE == IsSupportedFormatOp(pDriverCaps, TargetFormat, D3DFORMAT_MEMBEROFGROUP_ARGB)) + { + return D3DERR_NOTAVAILABLE; + } + + return D3D_OK; +} diff --git a/reactos/dll/directx/d3d9/format.h b/reactos/dll/directx/d3d9/format.h index cd6eec38f28..3d3cf7e202a 100644 --- a/reactos/dll/directx/d3d9/format.h +++ b/reactos/dll/directx/d3d9/format.h @@ -33,4 +33,6 @@ HRESULT CheckDeviceType(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT DisplayFormat, HRESULT CheckDeviceFormat(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat); +HRESULT CheckDeviceFormatConversion(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat); + #endif // _FORMAT_H_