バージョン検出のサポート
このセクションは、Windows 7 以降のオペレーティング システムのみに適用されます。
Windows Vista 以降のバージョンおよび Windows Server 2008 以降のバージョンで動作するユーザー モード ディスプレイ ドライバーは、ドライバーが明示的にサポートしていない DDI バージョンに関しては、アダプターの作成に失敗 (つまり、ドライバーの OpenAdapter10 関数の呼び出しに失敗) しなければなりません。
Windows 7 には、ドライバーが明示的にサポートする DDI バージョンとハードウェア機能を Direct3D アプリケーションで検出する手段が備わっています。 これにより、バージョン検証が向上します。 Windows 7 では、バージョン管理を改良して API とドライバーの初期化を最適化できるようにするために、アダプター固有の新しい関数が導入されています。 OpenAdapter10_2 関数を Direct3D バージョン 10.1 ドライバーで実装およびエクスポートし、Direct3D ランタイムがドライバーの新しいアダプター固有の関数を呼び出せるようにする必要があります。 代わりに、OpenAdapter10 を Direct3D バージョン 10.1 ドライバーで実装する場合、ドライバーが DDI バージョンをサポートしているかどうかは、OpenAdapter10 の呼び出しの成否によってのみ示されます。
OpenAdapter10_2 は、ドライバーのアダプター固有の関数のテーブルを、D3D10DDIARG_OPENADAPTER 構造体の pAdapterFuncs_2 メンバーに入れて返します。 pAdapterFuncs_2 は、D3D10_2DDI_ADAPTERFUNCS 構造体を指しています。 Direct3D ランタイムは、ドライバーのアダプター固有の GetSupportedVersions 関数を呼び出して、ドライバーでサポートされている DDI バージョンとハードウェア機能を照会します。 GetSupportedVersions は、64 ビット値の配列で DDI バージョンとハードウェア機能を返します。 次のコード例は、GetSupportedVersions の実装を示しています。
// Array of 64-bit values that are defined in D3d10umddi.h
const UINT64 c_aSupportedVersions[] = {
D3D10_0_7_DDI_SUPPORTED, // 10.0 on Windows 7
D3D10_0_DDI_SUPPORTED, // 10.0 on Windows Vista
D3D10_1_x_DDI_SUPPORTED, // 10.1 with all extended
// format support (but not
// Windows 7 scheduling)
};
HRESULT APIENTRY GetSupportedVersions(
D3D10DDI_HADAPTER hAdapter,
__inout UINT32* puEntries,
__out_ecount_opt( *puEntries )
UINT64* pSupportedDDIInterfaceVersions)
)
{
const UINT32 uEntries = ARRAYSIZE( c_aSupportedVersions );
if (pSupportedDDIInterfaceVersions &&
*puEntries < uEntries)
{
return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
}
// Determine concise hardware support from kernel, cache with hAdapter.
// pfnQueryAdapterInfoCb( hAdapter, ... )
*puEntries = uEntries;
if (pSupportedDDIInterfaceVersions)
{
UINT64* pCurEntry = pSupportedDDIInterfaceVersions;
memcpy( pCurEntry, c_aSupportedVersions, sizeof( c_aSupportedVersions ) );
pCurEntry += ARRAYSIZE( c_aSupportedVersions );
assert( pCurEntry - pSupportedDDIInterfaceVersions == uEntries );
}
return S_OK;
}
Direct3D バージョン 10.1 ドライバーでは、OpenAdapter10_2 関数への呼び出しで、Interface メンバーと Version メンバー (D3D10DDIARG_OPENADAPTER) に渡された値を検証する必要はありません。それらの値に、ドライバーの初期化に使用する DDI バージョン情報が含まれている場合であっても検証は不要です。 ドライバーは、GetSupportedVersions 関数を呼び出すことで、DDI バージョンとハードウェア機能を返すことができます。
Direct3D ランタイムは、ドライバーの CreateDevice(D3D10) 関数への呼び出しで Interface メンバーと Version メンバー (D3D10DDIARG_CREATEDEVICE) に、OpenAdapter10_2 に渡したのは異なる値を渡すことがあります。ランタイムが Interface メンバーと Version メンバー (D3D10DDIARG_CREATEDEVICE) に渡す値は、ドライバーの GetSupportedVersions がランタイムに返した DDI バージョンとハードウェア機能情報に基づいています。 ドライバーは、Interface メンバーと Version メンバー (D3D10DDIARG_CREATEDEVICE) に渡される値を検証する必要はありません。ドライバーは、これらの値のサポートを、GetSupportedVersions 関数によってすでに示しているからです。
ドライバーを Direct3D バージョン 10.0 から Direct3D バージョン 10.1 に移植する場合、OpenAdapter10_2 ではなく、CreateDevice(D3D10) に渡される Interface メンバーと Version メンバーのみを監視するようドライバーを変換する必要があります。 移植したドライバーで CalcPrivateDeviceSize 関数と CreateDevice(D3D10) 関数の両方の実装を分析し、Interface メンバーと Version メンバー (CreateDevice(D3D10)) の値が、Interfaceメンバーと Version メンバー (OpenAdapter10_2) の値と一致するという前提がないことを確かめます。
注OpenAdapter10_2 の関数シグネチャは OpenAdapter10 と同じです (つまり、D3d10umddi.h ヘッダーで定義されている PFND3D10DDI_OPENADAPTER)。 両方の関数を同じユーザー モード ディスプレイ ドライバー DLL に実装できます。