📄 zfxd3d_enum.cpp
字号:
return -1;
if (pdm1->RefreshRate > pdm2->RefreshRate)
return 1;
if (pdm1->RefreshRate < pdm2->RefreshRate)
return -1;
return 0;
} // SortModesCallback
/*----------------------------------------------------------------*/
HRESULT ZFXD3DEnum::EnumAdapters(void) {
D3DDISPLAYMODE d3ddspmd;
HRESULT hr;
UINT nNumAdapters=0;
UINT nNumModes=0;
if (!m_pD3D) return ZFX_INVALIDPARAM;
// get number of attached adapters
nNumAdapters = m_pD3D->GetAdapterCount();
// loop through adapters
for (UINT nAdapter=0; nAdapter<nNumAdapters; nAdapter++) {
m_xAdapterInfo[m_dwNumAdapters].nAdapter = nAdapter;
m_xAdapterInfo[m_dwNumAdapters].nNumModes = 0;
// get adapter information struct
m_pD3D->GetAdapterIdentifier(nAdapter, 0,
&m_xAdapterInfo[m_dwNumAdapters].
d3dAdapterIdentifier);
// loop through allowed bpp formats
for (UINT nFmt=0; nFmt<m_nNumFmt; nFmt++) {
// get available display modes for this adapter/bpp format
nNumModes = m_pD3D->GetAdapterModeCount(nAdapter, m_fmtAdapter[nFmt]);
for (UINT nMode=0; nMode<nNumModes; nMode++) {
// get number of available display modes
m_pD3D->EnumAdapterModes(nAdapter, m_fmtAdapter[nFmt],
nMode, &d3ddspmd);
// don't use less than we asked for
if (d3ddspmd.Width < m_nMinWidth ||
d3ddspmd.Height < m_nMinHeight ||
GetBits(d3ddspmd.Format) < m_nMinBits) {
continue;
}
// else save this mode
else {
m_xAdapterInfo[m_dwNumAdapters].d3ddspmd[
m_xAdapterInfo[m_dwNumAdapters].nNumModes] = d3ddspmd;
m_xAdapterInfo[m_dwNumAdapters].nNumModes++;
}
} // for [modes]
} // for [formats]
// we got the data, now sort it
qsort(m_xAdapterInfo[m_dwNumAdapters].d3ddspmd,
m_xAdapterInfo[m_dwNumAdapters].nNumModes,
sizeof(D3DDISPLAYMODE),
SortModesCallback);
if (FAILED(hr=EnumDevices(m_xAdapterInfo[m_dwNumAdapters])))
return hr;
// keep this one if any device is found
if (m_xAdapterInfo[m_dwNumAdapters].nNumDevs > 0)
m_dwNumAdapters++;
} // for [adapters]
return ZFX_OK;
} //EnumAdapters
/*----------------------------------------------------------------*/
HRESULT ZFXD3DEnum::EnumDevices(ZFXADAPTERINFO &xAdapter) {
ZFXDEVICEINFO *pDev;
HRESULT hr;
const D3DDEVTYPE d3dDevTypes[] = {
D3DDEVTYPE_HAL,
D3DDEVTYPE_SW,
D3DDEVTYPE_REF
};
xAdapter.nNumDevs = 0;
for (UINT nDev=0; nDev<3; nDev++) {
pDev = &xAdapter.d3dDevs[xAdapter.nNumDevs];
pDev->nNumCombo = 0;
pDev->nAdapter = xAdapter.nAdapter;
pDev->d3dDevType = d3dDevTypes[nDev];
// will fail if unsupported devtype
if (FAILED(m_pD3D->GetDeviceCaps(pDev->nAdapter,
pDev->d3dDevType, &pDev->d3dCaps)))
continue;
// this should not fail
if (FAILED(hr=EnumCombos(*pDev)))
return hr;
// at least one supportet combo?
if (pDev->nNumCombo <= 0)
continue;
// keep valid device
xAdapter.nNumDevs++;
} // for
return ZFX_OK;
} // EnumDevices
/*----------------------------------------------------------------*/
HRESULT ZFXD3DEnum::EnumCombos(ZFXDEVICEINFO &xDev) {
ZFXCOMBOINFO *pCombo;
bool bWindowed;
bool bFmtCheck=false;
bool bAny=false;
xDev.nNumCombo = 0;
// all adapter Formats
for (UINT nFmt_A=0; nFmt_A<m_nNumFmt; nFmt_A++) {
// for all allowed backbuffer formats
for (UINT nFmt_B=0; nFmt_B<g_nFormats_B; nFmt_B++) {
// check windowed and fullscreen
for (UINT n=0; n<2; n++) {
if (n==0) bWindowed=true;
else bWindowed=false;
// valid combo?
if (FAILED(m_pD3D->CheckDeviceType(
xDev.nAdapter,
xDev.d3dDevType,
m_fmtAdapter[nFmt_A],
g_fmtBackBuffer[nFmt_B],
bWindowed)))
continue;
// at this point we have a valid combo that is supported
// by the system. still need to find depth/stencil fmt
// and best vertex processing type.
pCombo = &xDev.d3dCombo[xDev.nNumCombo];
pCombo->nAdapter = xDev.nAdapter;
pCombo->d3dDevType = xDev.d3dDevType;
pCombo->bWindowed = bWindowed;
pCombo->fmtBackBuffer = g_fmtBackBuffer[nFmt_B];
pCombo->fmtAdapter = m_fmtAdapter[nFmt_A];
// SELECT DEPTH/STENCIL FORMAT
// select depth fmt & stencil buffer
if (m_nMinStencil) {
pCombo->fmtDepthStencil = D3DFMT_D24S8;
bFmtCheck = ConfirmDepthFmt(pCombo);
if (!bFmtCheck) {
pCombo->fmtDepthStencil = D3DFMT_D24X4S4;
bFmtCheck = ConfirmDepthFmt(pCombo);
}
if (!bFmtCheck) {
pCombo->fmtDepthStencil = D3DFMT_D15S1;
bFmtCheck = ConfirmDepthFmt(pCombo);
}
}
// or without stencil buffer
else {
if (m_nMinDepth > 24) {
pCombo->fmtDepthStencil = D3DFMT_D32;
bFmtCheck = ConfirmDepthFmt(pCombo);
}
if (!bFmtCheck && (m_nMinDepth > 16)) {
pCombo->fmtDepthStencil = D3DFMT_D24X8;
bFmtCheck = ConfirmDepthFmt(pCombo);
}
else {
pCombo->fmtDepthStencil = D3DFMT_D16;
bFmtCheck = ConfirmDepthFmt(pCombo);
}
}
// no suitable fmt => ignore this combo
if (!bFmtCheck) continue;
// SELECT VERTEX PROCESSING
// we have hardware T&L
if ((xDev.d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0) {
// 1.case: pure device
if ( ((xDev.d3dCaps.DevCaps & D3DDEVCAPS_PUREDEVICE)!=0)
&& (ConfirmDevice(&xDev.d3dCaps, D3DCREATE_PUREDEVICE,
pCombo->fmtBackBuffer)==ZFX_OK) ) {
pCombo->dwBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING
| D3DCREATE_PUREDEVICE;
bAny = true;
}
// 2.case: hardware device
else if (ConfirmDevice(&xDev.d3dCaps, D3DCREATE_HARDWARE_VERTEXPROCESSING,
pCombo->fmtBackBuffer)==ZFX_OK) {
pCombo->dwBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING;
bAny = true;
}
// 3.case: mixed sw/hw
else if (ConfirmDevice(&xDev.d3dCaps, D3DCREATE_MIXED_VERTEXPROCESSING,
pCombo->fmtBackBuffer)==ZFX_OK) {
pCombo->dwBehavior = D3DCREATE_MIXED_VERTEXPROCESSING;
bAny = true;
}
} // if [HW]
// 4.case: must be sw processing
else {
if (ConfirmDevice(&xDev.d3dCaps, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
pCombo->fmtBackBuffer)==ZFX_OK) {
pCombo->dwBehavior = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
bAny = true;
}
}
// none combo found that supports everything we need
if (!bAny) continue;
// SELECT MULTISAMPLE TYPE
DWORD msQuality;
for(UINT nMS=g_nMS-1; nMS>=0; nMS--) {
if (SUCCEEDED(m_pD3D->
CheckDeviceMultiSampleType(
pCombo->nAdapter,
pCombo->d3dDevType,
pCombo->fmtBackBuffer,
pCombo->bWindowed,
g_msType[nMS], &msQuality))) {
pCombo->msType = g_msType[nMS];
break;
}
} // for [multisample]
// NO WE GOT EVERYTHING WE NEE AND KEEP THIS COMBO
xDev.nNumCombo++;
} // for [windowed/fullscreen]
} // for [BackbufferFormats]
} // for [AdapterFormats]
return ZFX_OK;
}
/*----------------------------------------------------------------*/
bool ZFXD3DEnum::ConfirmDepthFmt(ZFXCOMBOINFO *pCombo) {
// compatible with adapter?
if (FAILED(m_pD3D->CheckDeviceFormat(pCombo->nAdapter,
pCombo->d3dDevType,
pCombo->fmtAdapter,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
pCombo->fmtDepthStencil)))
return false;
// compatible with backbuffer format?
if (FAILED(m_pD3D->CheckDepthStencilMatch(
pCombo->nAdapter,
pCombo->d3dDevType,
pCombo->fmtAdapter,
pCombo->fmtBackBuffer,
pCombo->fmtDepthStencil)))
return false;
return true;
} // ConfirmDepthFmt
/*----------------------------------------------------------------*/
HRESULT ZFXD3DEnum::ConfirmDevice(D3DCAPS9* pCaps, DWORD dwBehavior,
D3DFORMAT fmtBackbuffer) {
if ( (dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING) ||
(dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING) ) {
// alphablending from texture pixels supported
if ( !(pCaps->TextureCaps & D3DPTEXTURECAPS_ALPHA) ) {
fprintf(m_pLog, "[ZFXD3D_ENUM] error: no alphablending from texture \n");
return ZFX_FAIL;
}
}
return ZFX_OK;
} // ConfirmDevice
/*----------------------------------------------------------------*/
UINT ZFXD3DEnum::GetBits(D3DFORMAT fmt) {
switch(fmt) {
case D3DFMT_A2B10G10R10: return 30;
case D3DFMT_R8G8B8: return 24;
case D3DFMT_A8R8G8B8: return 24;
case D3DFMT_X8R8G8B8: return 24;
case D3DFMT_R5G6B5: return 16;
case D3DFMT_X1R5G5B5: return 15;
case D3DFMT_A1R5G5B5: return 15;
case D3DFMT_X4R4G4B4: return 12;
case D3DFMT_A4R4G4B4: return 12;
case D3DFMT_R3G3B2: return 8;
case D3DFMT_A8R3G3B2: return 8;
default: return 0;
}
} // GetBits
/*----------------------------------------------------------------*/
TCHAR* D3DDevTypeToString(D3DDEVTYPE devType) {
switch (devType) {
case D3DDEVTYPE_HAL: return TEXT("D3DDEVTYPE_HAL");
case D3DDEVTYPE_SW: return TEXT("D3DDEVTYPE_SW");
case D3DDEVTYPE_REF: return TEXT("D3DDEVTYPE_REF");
default: return TEXT("Unknown devType");
}
}
/*----------------------------------------------------------------*/
TCHAR* D3DFormatToString(D3DFORMAT format) {
switch (format) {
case D3DFMT_UNKNOWN: return TEXT("D3DFMT_UNKNOWN");
case D3DFMT_R8G8B8: return TEXT("D3DFMT_R8G8B8");
case D3DFMT_A8R8G8B8: return TEXT("D3DFMT_A8R8G8B8");
case D3DFMT_X8R8G8B8: return TEXT("D3DFMT_X8R8G8B8");
case D3DFMT_R5G6B5: return TEXT("D3DFMT_R5G6B5");
case D3DFMT_X1R5G5B5: return TEXT("D3DFMT_X1R5G5B5");
case D3DFMT_A1R5G5B5: return TEXT("D3DFMT_A1R5G5B5");
case D3DFMT_A4R4G4B4: return TEXT("D3DFMT_A4R4G4B4");
case D3DFMT_R3G3B2: return TEXT("D3DFMT_R3G3B2");
case D3DFMT_A8R3G3B2: return TEXT("D3DFMT_A8R3G3B2");
case D3DFMT_X4R4G4B4: return TEXT("D3DFMT_X4R4G4B4");
case D3DFMT_A2B10G10R10: return TEXT("D3DFMT_A2B10G10R10");
case D3DFMT_D16_LOCKABLE: return TEXT("D3DFMT_D16_LOCKABLE");
case D3DFMT_D32: return TEXT("D3DFMT_D32");
case D3DFMT_D15S1: return TEXT("D3DFMT_D15S1");
case D3DFMT_D24S8: return TEXT("D3DFMT_D24S8");
case D3DFMT_D16: return TEXT("D3DFMT_D16");
case D3DFMT_D24X8: return TEXT("D3DFMT_D24X8");
case D3DFMT_D24X4S4: return TEXT("D3DFMT_D24X4S4");
case D3DFMT_VERTEXDATA: return TEXT("D3DFMT_VERTEXDATA");
case D3DFMT_INDEX16: return TEXT("D3DFMT_INDEX16");
case D3DFMT_INDEX32: return TEXT("D3DFMT_INDEX32");
default: return TEXT("Unknown format");
}
}
/*----------------------------------------------------------------*/
TCHAR* BehaviorTypeToString(DWORD vpt) {
switch (vpt) {
case D3DCREATE_SOFTWARE_VERTEXPROCESSING: return TEXT("SOFTWARE_VP");
case D3DCREATE_MIXED_VERTEXPROCESSING: return TEXT("MIXED_VP");
case D3DCREATE_HARDWARE_VERTEXPROCESSING: return TEXT("HARDWARE_VP");
case D3DCREATE_PUREDEVICE: return TEXT("PURE_HARDWARE_VP");
default: return TEXT("Unknown VP");
}
}
/*----------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -