IDXGIDevice4
COM公式ドキュメント
リソースのオファーと再要求を行うための更新されたメソッドを提供するインターフェイスです。
解説(Remarks)
Direct3D のデバイス作成関数は、Direct3D デバイスオブジェクトを返します。この Direct3D デバイスオブジェクトは IUnknown インターフェイスを実装しています。この Direct3D デバイスオブジェクトに対してクエリを行うことで、デバイスに対応する IDXGIDevice4 インターフェイスを取得できます。Direct3D デバイスの IDXGIDevice4 インターフェイスを取得するには、次のコードを使用します。
IDXGIDevice4 * pDXGIDevice;
hr = g_pd3dDevice->QueryInterface(__uuidof(IDXGIDevice4), (void **)&pDXGIDevice);
メソッド 2
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
オペレーティングシステムがリソースのビデオメモリを解放できるようにします。これには、コンテンツの破棄とメモリのコミット解除の両方が含まれます。
| NumResources | DWORD | in | ppResources 引数の配列に含まれるリソースの数。 |
| ppResources | IDXGIResource** | in | オファーするリソースの IDXGIResource インターフェイスへのポインターの配列。 |
| Priority | DXGI_OFFER_RESOURCE_PRIORITY | in | データの重要度を示す DXGI_OFFER_RESOURCE_PRIORITY 型の値。 |
| Flags | DWORD | in | DXGI_OFFER_RESOURCE_FLAGS を指定します。 |
戻り値
Type: HRESULT
このメソッドは HRESULT の成功コードまたはエラーコードを返します。配列内のリソースまたは優先度が無効な場合は、E_INVALIDARG が含まれることがあります。
解説(Remarks)
OfferResources1(元の IDXGIDevice2::OfferResources API の拡張)を使用すると、D3D ベースのアプリケーションは、メモリ不足の状況でシステムコミットを削減するために、アロケーションのバッキングストアのコミット解除を許可できます。 コミット解除されたアロケーションは再利用できないため、新しい DXGI_OFFER_RESOURCE_FLAG_ALLOW_DECOMMIT フラグを有効にする場合は、新しい再要求結果を適切に処理する必要があります。DXGI_RECLAIM_RESOURCE_RESULTS のフラグの説明と、以下の例を参照してください。
OfferResources1 と ReclaimResources1 は、OfferResources および ReclaimResources と相互に入れ替えて使用することはできません。
Priority パラメーターで指定する優先度の値は、呼び出し元がそのコンテンツをどの程度重要と見なしているかを表します。オペレーティングシステムは、この優先度の値を使用して、優先度の順にリソースを破棄します。オペレーティングシステムは、より高い優先度でオファーされたリソースよりも先に、低い優先度でオファーされたリソースを破棄します。
リソースがパイプラインにバインドされている状態で OfferResources1 を呼び出してそのリソースをオファーすると、そのリソースのバインドは解除されます。マップされているリソースに対して OfferResources1 を呼び出すことはできません。リソースをオファーした後は、ReclaimResources1 メソッドを呼び出してそのリソースを再要求するまで、そのリソースをマップしたりパイプラインにバインドしたりすることはできません。イミュータブル(変更不可)なリソースを OfferResources1 でオファーすることはできません。
共有リソースをオファーするには、共有しているデバイスのうちの 1 つでのみ OfferResources1 を呼び出します。リソースへの排他的アクセスを保証するには、IDXGIKeyedMutex(キー付きミューテックス)オブジェクトを使用し、そのミューテックスを保持している間のみ OfferResources1 を呼び出す必要があります。実際、IDXGIKeyedMutex を使用せずに共有リソースをオファーすることはサポートされていないため、IDXGIKeyedMutex を使用しない限り共有リソースをオファーすることはできません。
ユーザーモードのディスプレイドライバーは、OfferResources1 の呼び出しで指定したリソースをすぐにはオファーしない場合があります。ドライバーは、次に IDXGISwapChain::Present、IDXGISwapChain1::Present1、または ID3D11DeviceContext::Flush が呼び出されるまで、オファーを延期することがあります。
例
UWP ベースのアプリケーションがバックグラウンドにサスペンドされようとしており、別のアプリケーションがそれらを必要とする場合に備えて、自身のグラフィックスリソースをシステムに返すためにオファーしようとしています。このアプリケーションは、再開されたときにこれらのリソースを再要求します。また、このアプリケーションは、このプラットフォームでは利用可能なシステムコミットの合計が小さいことを認識しており、自身のリソースがシステムコミットから削除されることを許容する意向です。システムのメモリ不足によって再要求処理が失敗した場合、アプリケーションはそのエラー状態を処理します。
struct Texture
{
UINT32 Width;
UINT32 Height;
UINT32 Mips;
ID3D11Texture2D* pResource;
};
void Application::OfferInterfaceResources(ID3D11Device* pD3D11Device)
{
CComPtr<IDXGIDevice4> pDXGIDevice;
ThrowIfFailed(pD3D11Device->QueryInterface(&pDXGIDevice));
for(Texture& t : m_Textures)
{
CComPtr<IDXGIResource> pDXGIResource;
ThrowIfFailed(t.pResource->QueryInterface(&pDXGIResource));
ThrowIfFailed(pDXGIDevice->OfferResources1(1, &pDXGIResource, DXGI_OFFER_RESOURCE_PRIORITY_NORMAL,
DXGI_OFFER_RESOURCE_FLAG_ALLOW_DECOMMIT));
}
}
void Application::ReclaimInterfaceResources (ID3D11Device* pD3D11Device)
{
CComPtr<IDXGIDevice4> pDXGIDevice;
ThrowIfFailed(pD3D11Device->QueryInterface(&pDXGIDevice));
for(Texture& t : m_Textures)
{
CComPtr<IDXGIResource> pDXGIResource;
ThrowIfFailed(t.pResource->QueryInterface(&pDXGIResource));
DXGI_RECLAIM_RESOURCE_RESULTS Result;
ThrowIfFailed(pDXGIDevice->ReclaimResources1(1, &pDXGIResource, &Result));
// If the surface lost its backing commitment, it must be recreated.
if(Result == DXGI_RECLAIM_RESOURCE_RESULT_NOT_COMMITTED)
{
t.pResource->Release();
t.pResource = CreateTexture(t.Width, t.Height, t.Mips);
}
// If the surface lost its content (either because it was discarded, or recreated
// due to lost commitment), we must regenerate the content.
if(Result != DXGI_RECLAIM_RESOURCE_RESULT_OK)
{
PopulateContent(t);
}
}
}
IDXGIDevice4::OfferResources1 の呼び出しによって以前にオファーされたリソースへのアクセスを復元します。
| NumResources | DWORD | in | ppResources 引数および pResults 引数の配列に含まれるリソースの数。 |
| ppResources | IDXGIResource** | in | 再要求するリソースの IDXGIResource インターフェイスへのポインターの配列。 |
| pResults | DXGI_RECLAIM_RESOURCE_RESULTS* | out | DXGI_RECLAIM_RESOURCE_RESULTS の値を受け取る配列へのポインター。配列内の各値は、ppResources パラメーターで指定される同じインデックスのリソースに対応します。以前のコンテンツが破棄されたかどうかに関係なくリソースを新しいコンテンツで埋める予定である場合、呼び出し元は NULL を渡すことができます。 |
戻り値
Type: HRESULT
このメソッドは HRESULT の成功コードまたはエラーコードを返します。リソースが無効な場合は E_INVALIDARG が含まれます。
解説(Remarks)
OfferResources1 を呼び出して 1 つ以上のリソースをオファーした後は、それらのリソースを再び使用する前に ReclaimResources1 を呼び出す必要があります。
共有リソースを再要求するには、共有しているデバイスのうちの 1 つでのみ ReclaimResources1 を呼び出します。リソースへの排他的アクセスを保証するには、IDXGIKeyedMutex(キー付きミューテックス)オブジェクトを使用し、そのミューテックスを保持している間のみ ReclaimResources1 を呼び出す必要があります。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IDXGIDevice4 "{95B4F95F-D8DA-4CA4-9EE6-3B76D5968A10}" #usecom global IDXGIDevice4 IID_IDXGIDevice4 "{}" #comfunc global IDXGIDevice4_OfferResources1 18 int,sptr,int,int #comfunc global IDXGIDevice4_ReclaimResources1 19 int,sptr,var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IDXGIDevice4 "{95B4F95F-D8DA-4CA4-9EE6-3B76D5968A10}" #usecom global IDXGIDevice4 IID_IDXGIDevice4 "{}" #comfunc global IDXGIDevice4_OfferResources1 18 int,sptr,int,int #comfunc global IDXGIDevice4_ReclaimResources1 19 int,sptr,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。