windows-nt/Source/XPSP1/NT/multimedia/directx/dxdiag/dispinfo8.cpp
2020-09-26 16:20:57 +08:00

262 lines
8.7 KiB
C++

/****************************************************************************
*
* File: dispinfo8.cpp
* Project: DxDiag (DirectX Diagnostic Tool)
* Author: Jason Sandlin (jasonsa@microsoft.com)
* Purpose: Gather D3D8 information
*
* (C) Copyright 2000 Microsoft Corp. All rights reserved.
*
****************************************************************************/
#include <tchar.h>
#include <Windows.h>
#define DIRECT3D_VERSION 0x0800 // file uses DX8
#include <d3d8.h>
#include <stdio.h>
#include "sysinfo.h"
#include "reginfo.h"
#include "dispinfo.h"
typedef IDirect3D8* (WINAPI* LPDIRECT3DCREATE8)(UINT SDKVersion);
static BOOL IsMatchWithDisplayDevice( DisplayInfo* pDisplayInfo, HMONITOR hMonitor, BOOL bCanRenderWindow );
static HINSTANCE s_hInstD3D8 = NULL;
static IDirect3D8* s_pD3D8 = NULL;
static BOOL s_bD3D8WrongHeaders = FALSE;
/****************************************************************************
*
* InitD3D8
*
****************************************************************************/
HRESULT InitD3D8()
{
LPDIRECT3DCREATE8 pD3DCreate8 = NULL;
TCHAR szPath[MAX_PATH];
GetSystemDirectory(szPath, MAX_PATH);
lstrcat(szPath, TEXT("\\d3d8.dll"));
// This may fail if DX8 isn't on the system
s_hInstD3D8 = LoadLibrary(szPath);
if (s_hInstD3D8 == NULL)
return E_FAIL;
pD3DCreate8 = (LPDIRECT3DCREATE8)GetProcAddress(s_hInstD3D8, "Direct3DCreate8");
if (pD3DCreate8 == NULL)
{
FreeLibrary(s_hInstD3D8);
s_hInstD3D8 = NULL;
return E_FAIL;
}
s_pD3D8 = pD3DCreate8(D3D_SDK_VERSION);
if( s_pD3D8 == NULL )
{
// We have the wrong headers since d3d8.dll loaded but D3DCreate8() failed.
s_bD3D8WrongHeaders = TRUE;
}
return S_OK;
}
/****************************************************************************
*
* CleanupD3D8
*
****************************************************************************/
VOID CleanupD3D8()
{
if( s_pD3D8 )
{
s_pD3D8->Release();
s_pD3D8 = NULL;
}
if( s_hInstD3D8 )
{
FreeLibrary(s_hInstD3D8);
s_hInstD3D8 = NULL;
}
}
/****************************************************************************
*
* IsD3D8Working
*
****************************************************************************/
BOOL IsD3D8Working()
{
if( s_pD3D8 )
return TRUE;
else
return FALSE;
}
/****************************************************************************
*
* GetDX8AdapterInfo
*
****************************************************************************/
HRESULT GetDX8AdapterInfo(DisplayInfo* pDisplayInfo)
{
UINT nAdapterCount;
D3DADAPTER_IDENTIFIER8 d3d8Id;
D3DCAPS8 d3d8Caps;
UINT iAdapter;
HMONITOR hMonitor;
BOOL bCanRenderWindow;
BOOL bIsDDI8;
// D3D8 may not exist on this system
if( s_pD3D8 == NULL )
{
_tcscpy( pDisplayInfo->m_szDX8DriverSignDate, TEXT("n/a") );
_tcscpy( pDisplayInfo->m_szDX8VendorId, TEXT("n/a") );
_tcscpy( pDisplayInfo->m_szDX8DeviceId, TEXT("n/a") );
_tcscpy( pDisplayInfo->m_szDX8SubSysId, TEXT("n/a") );
_tcscpy( pDisplayInfo->m_szDX8Revision, TEXT("n/a") );
if( s_bD3D8WrongHeaders )
{
_tcscpy( pDisplayInfo->m_szDX8DeviceIdentifier,
TEXT("Could not initialize Direct3D v8. ")
TEXT("This program was compiled with header ")
TEXT("files that do not match the installed ")
TEXT("DirectX DLLs") );
}
else
{
_tcscpy( pDisplayInfo->m_szDX8DeviceIdentifier, TEXT("n/a") );
}
return S_OK;
}
// Get the # of adapters on the system
nAdapterCount = s_pD3D8->GetAdapterCount();
// For each adapter try to match it to the pDisplayInfo using the HMONTIOR
for( iAdapter=0; iAdapter<nAdapterCount; iAdapter++ )
{
bCanRenderWindow = TRUE;
bIsDDI8 = FALSE;
// Get the HMONITOR for this adapter
hMonitor = s_pD3D8->GetAdapterMonitor( iAdapter );
// Get the caps for this adapter
ZeroMemory( &d3d8Caps, sizeof(D3DCAPS8) );
if( SUCCEEDED( s_pD3D8->GetDeviceCaps( iAdapter, D3DDEVTYPE_HAL, &d3d8Caps ) ) )
{
// Record if its a non-GDI (Voodoo1/2) card
bCanRenderWindow = ( (d3d8Caps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) != 0 );
// Check if its a DDI v8 driver
bIsDDI8 = ( d3d8Caps.MaxStreams > 0 );
}
// Check to see if the pDisplayInfo matchs with this adapter,
// and if not, then keep looking
if( !IsMatchWithDisplayDevice( pDisplayInfo, hMonitor, bCanRenderWindow ) )
continue;
// Record the DDI version if the caps told us
if( bIsDDI8 )
pDisplayInfo->m_dwDDIVersion = 8;
// Link this iAdapter to this pDisplayInfo
pDisplayInfo->m_iAdapter = iAdapter;
// Get the D3DADAPTER_IDENTIFIER8 for this adapter
ZeroMemory( &d3d8Id, sizeof(D3DADAPTER_IDENTIFIER8) );
if( SUCCEEDED( s_pD3D8->GetAdapterIdentifier( iAdapter, 0, &d3d8Id ) ) )
{
// Copy various IDs
wsprintf( pDisplayInfo->m_szDX8VendorId, TEXT("0x%04.4X"), d3d8Id.VendorId );
wsprintf( pDisplayInfo->m_szDX8DeviceId, TEXT("0x%04.4X"), d3d8Id.DeviceId );
wsprintf( pDisplayInfo->m_szDX8SubSysId, TEXT("0x%08.8X"), d3d8Id.SubSysId );
wsprintf( pDisplayInfo->m_szDX8Revision, TEXT("0x%04.4X"), d3d8Id.Revision );
// Copy device GUID
pDisplayInfo->m_guidDX8DeviceIdentifier = d3d8Id.DeviceIdentifier;
_stprintf( pDisplayInfo->m_szDX8DeviceIdentifier, TEXT("{%08.8X-%04.4X-%04.4X-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X}"),
d3d8Id.DeviceIdentifier.Data1, d3d8Id.DeviceIdentifier.Data2, d3d8Id.DeviceIdentifier.Data3,
d3d8Id.DeviceIdentifier.Data4[0], d3d8Id.DeviceIdentifier.Data4[1],
d3d8Id.DeviceIdentifier.Data4[2], d3d8Id.DeviceIdentifier.Data4[3],
d3d8Id.DeviceIdentifier.Data4[4], d3d8Id.DeviceIdentifier.Data4[5],
d3d8Id.DeviceIdentifier.Data4[6], d3d8Id.DeviceIdentifier.Data4[7] );
// Copy and parse the WHQLLevel
// 0 == Not signed.
// 1 == WHQL signed, but no date information is available.
// >1 means signed, date bit packed
pDisplayInfo->m_dwDX8WHQLLevel = d3d8Id.WHQLLevel;
if( d3d8Id.WHQLLevel == 0 )
{
pDisplayInfo->m_bDX8DriverSigned = FALSE;
pDisplayInfo->m_bDX8DriverSignedValid = TRUE;
}
else
{
pDisplayInfo->m_bDX8DriverSigned = TRUE;
pDisplayInfo->m_bDX8DriverSignedValid = TRUE;
pDisplayInfo->m_bDriverSigned = TRUE;
pDisplayInfo->m_bDriverSignedValid = TRUE;
if( d3d8Id.WHQLLevel == 1 )
{
lstrcpy( pDisplayInfo->m_szDX8DriverSignDate, TEXT("n/a") );
}
else
{
// Bits encoded as:
// 31-16: The year, a decimal number from 1999 upwards.
// 15-8: The month, a decimal number from 1 to 12.
// 7-0: The day, a decimal number from 1 to 31.
DWORD dwMonth, dwDay, dwYear;
dwYear = (d3d8Id.WHQLLevel >> 16);
dwMonth = (d3d8Id.WHQLLevel >> 8) & 0x000F;
dwDay = (d3d8Id.WHQLLevel >> 0) & 0x000F;
wsprintf( pDisplayInfo->m_szDX8DriverSignDate,
TEXT("%d/%d/%d"), dwMonth, dwDay, dwYear );
}
}
}
return S_OK;
}
// Hmm. This shouldn't happen since we should have found a match...
return E_FAIL;
}
/****************************************************************************
*
* IsMatchWithDisplayDevice
*
****************************************************************************/
BOOL IsMatchWithDisplayDevice( DisplayInfo* pDisplayInfo, HMONITOR hMonitor,
BOOL bCanRenderWindow )
{
// If the HMONITORs and the bCanRenderWindow match, then its good
if( pDisplayInfo->m_hMonitor == hMonitor &&
pDisplayInfo->m_bCanRenderWindow == bCanRenderWindow )
return TRUE;
else
return FALSE;
}