DXGKDDI_RENDER コールバック関数 (d3dkmddi.h)
DxgkDdiRender 関数は、ユーザー モードディスプレイ ドライバーが渡したコマンド バッファーからダイレクト メモリ アクセス (DMA) バッファーを生成します。
構文
DXGKDDI_RENDER DxgkddiRender;
NTSTATUS DxgkddiRender(
[in] IN_CONST_HANDLE hContext,
[in/out] INOUT_PDXGKARG_RENDER pRender
)
{...}
パラメーター
[in] hContext
DMA バッファーとコマンド バッファーのデバイス コンテキストへのハンドル。 ディスプレイ ミニポート ドライバーの DxgkDdiCreateContext 関数は、DxgkDdiCreateContext の pCreateContext パラメーターが指すDXGKARG_CREATECONTEXT構造体の hContext メンバーで、このハンドルを以前に返しました。
ドライバーがコンテキストの作成をサポートしていない場合、Microsoft DirectX グラフィックス カーネル サブシステムは、コンテキストへのハンドルをデバイスへのハンドルに置き換えます。 ディスプレイ ミニポート ドライバーの DxgkDdiCreateDevice 関数は、DxgkDdiCreateDevice の pCreateDevice パラメーターが指すDXGKARG_CREATEDEVICE構造体の hDevice メンバーでデバイス ハンドルを以前に返しました。
[in/out] pRender
DMA バッファーとコマンド バッファーに関する情報を含む DXGKARG_RENDER 構造体へのポインター。
戻り値
DxgkDdiRender は 、次のいずれかの値を返します。
リターン コード | 説明 |
---|---|
STATUS_SUCCESS | コマンド バッファー全体が変換されました。 |
STATUS_NO_MEMORY | DxgkDdiRender は、完了するために必要なメモリを割り当てませんでした。 |
STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER | 現在の DMA バッファーが不足しています。 |
STATUS_PRIVILEGED_INSTRUCTION | DxgkDdiRender は、特権のない命令 (つまり、現在の中央処理装置 [CPU] プロセスの特権を超えてメモリにアクセスする命令) を検出しました。 |
STATUS_ILLEGAL_INSTRUCTION | DxgkDdiRender によって、グラフィックス ハードウェアでサポートできない命令が検出されました。 |
STATUS_INVALID_PARAMETER | DxgkDdiRender は、グラフィックス ハードウェアでサポートできない命令パラメーターを検出しました。ただし、グラフィックス ハードウェアは命令自体をサポートできます。 ドライバーは、このエラー コードを返す必要はありません。 代わりに、サポートされていない命令パラメーターを検出したときにSTATUS_ILLEGAL_INSTRUCTIONを返すことができます。 |
STATUS_INVALID_USER_BUFFER | DxgkDdiRender によって、データまたは命令のアンダーランまたはオーバーランが検出されました。 つまり、ドライバーは予想よりも少ない、またはそれ以上の命令またはデータを受け取った。 ドライバーは、このエラー コードを返す必要はありません。 代わりに、データまたは命令のアンダーランまたはオーバーランが検出されたときにSTATUS_ILLEGAL_INSTRUCTIONを返すことができます。 |
STATUS_INVALID_HANDLE | DxgkDdiRender がコマンド バッファーで無効なハンドルを検出しました。 |
STATUS_GRAPHICS_DRIVER_MISMATCH | ディスプレイ ミニポート ドライバーは、DxgkDdiRender (つまり、コマンド バッファーを送信) への呼び出しを開始したユーザー モードディスプレイ ドライバーと互換性がありません。 |
STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE | ディスプレイ ミニポート ドライバーは、DMA ストリームでエラーを検出しました。 ドライバーがこのエラー コードを返した場合、グラフィックス コンテキスト デバイスは失われた状態になります。 |
注釈
DirectX グラフィックス カーネル サブシステムは、ディスプレイ ミニポート ドライバーの DxgkDdiRender 関数を呼び出して、ユーザー モードディスプレイ ドライバーが渡したコマンド バッファーから DMA バッファーを生成します。 ディスプレイ ミニポート ドライバーがコマンド バッファーから DMA バッファーに変換する場合、ドライバーはコマンド バッファーも検証して、コマンド バッファーに、プロセスに属していないメモリへのアクセスに使用できる特権コマンドまたはコマンドが含まれていないことを確認する必要があります。 出力 DMA バッファーに加えて、ディスプレイ ミニポート ドライバーは、出力パッチの場所の一覧も生成する必要があります。 ビデオ メモリ マネージャーでは、この一覧を使用して DMA バッファーを適切に分割してパッチを適用します。
コマンド バッファー pCommand と、ユーザー モードディスプレイ ドライバーによって生成される入力パッチの場所リスト pPatchLocationListIn の 両方が、ユーザー モードのアドレス空間から割り当てられ、手つかずでディスプレイ ミニポート ドライバーに渡されます。 ディスプレイ ミニポート ドライバーは、バッファーとリストへの任意のアクセスでコードを使用__try/__except
する必要があり、各カーネル バッファーにコンテンツをコピーする前にバッファーとリストの内容を検証する必要があります (つまり、pCommand メンバーのコンテンツを pDmaBuffer メンバーにコピーし、pPatchLocationListIn メンバーのコンテンツを pPatchLocationListOut メンバーにコピーする前に)pRender パラメーターが指すDXGKARG_RENDER構造体のすべてのメンバーです)。
ディスプレイ ミニポート ドライバーが と __except
ロジックを使用してこれらのバッファーにアクセスする方法の例を__try
次に示します。 AllocationListIn は 、ユーザー モード バッファーを指します。
__try
{
for (Index = 0; Index < AllocationListInSize; AllocationTable++,
AllocationListIn++, AllocationListOut++, Index++)
{
D3DKMT_HANDLE AllocationHandle = AllocationListIn->hAllocation;
. . .
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
Status = STATUS_INVALID_PARAMETER;
SAMPLE_LOG_ERROR(
"Exception occurred accessing user-mode allocation list. Returning Status=0x%I64x",
Status);
goto cleanup;
}
注意
カーネル バッファーへのアクセスには、コードからの try/except
保護は必要ありません。
ディスプレイ ミニポート ドライバーは、情報の再作成がより最適な場合、ユーザー モードディスプレイ ドライバーが提供する情報を使用する必要はありません。 たとえば、 pPatchLocationListIn が空の場合、ユーザー モードのディスプレイ ドライバーが入力パッチの場所の一覧を提供しなかったために、ディスプレイ ミニポート ドライバーは、代わりにコマンド バッファーの内容に基づいて pPatchLocationListOut のコンテンツを生成できます。
ユーザー モード ディスプレイ ドライバーが提供する割り当てリストは、カーネル遷移中に検証、コピー、およびカーネル モード割り当てリストに変換されます。 DirectX グラフィックス カーネル サブシステムは、ユーザー モードディスプレイ ドライバーが提供するD3DKMT_HANDLE型のハンドルをデバイス固有のハンドルに変換することで、各D3DDDI_ALLOCATIONLIST要素をDXGK_ALLOCATIONLIST要素に変換します。このハンドルは、ディスプレイ ミニポート ドライバーの DxgkDdiOpenAllocation 関数が返します。 各割り当てのインデックスと割り当ての書き込み状態 (つまり、 WriteOperation ビット フィールド フラグの設定) は、変換中も一定のままです。
DirectX グラフィックス カーネル サブシステムは、デバイス固有のハンドルに加えて、各割り当ての最後の既知の GPU セグメント アドレスをディスプレイ ミニポート ドライバーに提供します。 割り当てインデックス N が現在ページアウトされている場合、DirectX グラフィックス カーネル サブシステムは、DXGKARG_RENDER の pAllocationList メンバーの N番目の要素の SegmentId メンバーを 0 に設定します。 割り当てリストの N番目の要素の SegmentId メンバーが 0 に設定されていない場合、ディスプレイ ミニポート ドライバーは、指定されたセグメント アドレス情報を使用して、生成された DMA バッファーに事前にパッチを適用する必要があります。 DirectX グラフィックス カーネル サブシステムが DMA バッファーで DxgkDdiPatch 関数を呼び出さない可能性があるため、ドライバーは要求時に事前修正プログラムを適用する必要があります。この関数は、ドライバーに正しく事前パッチを適用する必要があります。
注意
ドライバーの DxgkDdiRender 関数は DMA バッファーに事前修正プログラムを適用しますが、DXGKARG_RENDERの pPatchLocationListOut メンバーが指定する出力パッチの場所リストに割り当てへのすべての参照 を 挿入する必要があります。 DMA バッファーが GPU に送信される前に割り当てのアドレスが変更される可能性があるため、このリストにはすべての参照が含まれている必要があります。したがって、DirectX グラフィックス カーネル サブシステムは DxgkDdiPatch 関数を呼び出して DMA バッファーを再パッチします。
割り当てをバインド解除するには、ディスプレイ ミニポート ドライバーは 、NULL ハンドルを参照する割り当てリスト内の要素を指定し、その NULL 割り当てを参照するパッチの場所要素を使用できます。 通常、ドライバーでは、割り当てリストの最初の要素 (要素 0) を NULL 要素として使用する必要があります。
ディスプレイ ミニポート ドライバーがコマンド バッファーを DMA バッファーに変換すると、ディスプレイ ミニポート ドライバーとユーザー モードディスプレイ ドライバーは、次の状況に対して次のアクションを実行する必要があります。
保証されたコントラクト DMA モードでは (詳細については、「 保証されたコントラクト DMA バッファー モデルの使用」を参照)、ユーザー モードディスプレイ ドライバーは変換コマンドに十分なリソースを保証する必要があります。 翻訳に十分なリソースが存在しない場合、ディスプレイ ミニポート ドライバーは DMA バッファーを拒否する必要があります。
ディスプレイ ミニポート ドライバーの DxgkDdiRender 関数は DMA バッファーのサイズよりも大きく、分割できない 1 つのコマンドを処理できないため、ユーザー モードディスプレイ ドライバーは常に、1 つの DMA バッファーのサイズを超える可能性があるコマンドを分割する必要があります。
DxgkDdiRender をページング可能にする必要があります。
DXgkDdiRenderKm 関数のサポートは、GDI ハードウェア アクセラレーションをサポートするディスプレイ アダプター用の Windows 7 以降に追加されました。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows Vista 以降で使用可能 |
対象プラットフォーム | デスクトップ |
Header | d3dkmddi.h |
IRQL | PASSIVE_LEVEL |