IDXGIResource1
COM公式ドキュメント
IDXGIResource1 インターフェイスは、サブリソースサーフェスオブジェクトの作成と、共有リソースへのハンドルの作成のサポートを追加することで、IDXGIResource インターフェイスを拡張します。
解説(Remarks)
リソースが現在配置されているメモリの種類を判別するには、IDXGIDevice::QueryResourceResidency を使用します。 プロセス間でリソースを共有するには、ID3D11Device1::OpenSharedResource1 を使用します。 Direct3D 11、Direct2D、Direct3D 10、Direct3D 9Ex などの複数の Windows グラフィックス API 間でリソースを共有する方法については、Surface Sharing Between Windows Graphics APIs を参照してください。
IDXGIResource1 インターフェイスは、Direct3D 10 以降の関数から作成した任意のビデオメモリリソースから取得できます。ID3D10Resource または ID3D11Resource をサポートする Direct3D オブジェクトはすべて IDXGIResource1 もサポートします。たとえば、ID3D11Device::CreateTexture2D から作成する Direct3D 2D テクスチャオブジェクトは IDXGIResource1 をサポートします。2D テクスチャオブジェクト(ID3D11Texture2D)に対して QueryInterface を呼び出すことで IDXGIResource1 インターフェイスを取得できます。たとえば、2D テクスチャオブジェクトから IDXGIResource1 インターフェイスを取得するには、次のコードを使用します。
IDXGIResource1 * pDXGIResource;
hr = g_pd3dTexture2D->QueryInterface(__uuidof(IDXGIResource1), (void **)&pDXGIResource);
Windows Phone 8: この API はサポートされています。
メソッド 2
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
サブリソースサーフェスオブジェクトを作成します。
| index | DWORD | in | 列挙するサブリソースサーフェスオブジェクトのインデックス。 |
| ppSurface | IDXGISurface2** | out | index パラメーターで指定された位置に作成されたサブリソースサーフェスオブジェクトを表す IDXGISurface2 インターフェイスへのポインターのアドレス。 |
戻り値
成功した場合は S_OK を返します。それ以外の場合は、次のいずれかの値を返します。
- インデックスが範囲外の場合、またはサブリソースが有効なサーフェスでない場合は DXGI_ERROR_INVALID_CALL。
- サブリソースサーフェスオブジェクトを作成するのに十分なメモリがない場合は E_OUTOFMEMORY。
解説(Remarks)
サブリソースサーフェスオブジェクトは IDXGISurface2 インターフェイスを実装します。これは IDXGISurface1 を継承し、間接的に IDXGISurface を継承します。 したがって、元のリソースインターフェイスオブジェクトが GDI 相互運用フラグ(D3D11_RESOURCE_MISC_GDI_COMPATIBLE)を指定して作成されていれば、IDXGISurface1 の GDI 相互運用メソッドが機能します。
CreateSubresourceSurface は、CreateSubresourceSurface を呼び出したリソースインターフェイスに基づくサブリソースサーフェスを作成します。たとえば、元のリソースインターフェイスオブジェクトが 2D テクスチャの場合、作成されるサブリソースサーフェスも 2D テクスチャになります。
CreateSubresourceSurface を使用してステレオリソースの一部を作成すると、ステレオリソースの左側または右側の部分に対して Direct2D を使用できます。
共有リソースへのハンドルを作成します。返されたハンドルは複数の Direct3D デバイスで使用できます。
| pAttributes | SECURITY_ATTRIBUTES* | inoptional | SECURITY_ATTRIBUTES 構造体へのポインター。この構造体には、独立しているが関連する 2 つのデータメンバー、すなわち省略可能なセキュリティ記述子と、子プロセスが返されたハンドルを継承できるかどうかを決定するブール値が含まれます。 アプリケーションが作成する可能性のある子プロセスに CreateSharedHandle が返すハンドルを継承させたくない場合、および返されたハンドルに関連付けられたリソースに既定のセキュリティ 記述子を割り当てたい場合は、このパラメーターを NULL に設定します。 構造体の lpSecurityDescriptor メンバーは、リソースの SECURITY_DESCRIPTOR を指定します。返されたハンドルに関連付けられたリソースにランタイムが既定のセキュリティ記述子を割り当てるようにするには、このメンバーを NULL に設定します。リソースの既定のセキュリティ記述子内の ACL は、作成者のプライマリトークンまたは偽装トークンに由来します。詳細については、Synchronization Object Security and Access Rights を参照してください。 |
| dwAccess | DWORD | in | リソースに対して要求されるアクセス権。 DXGI は、汎用アクセス権に加えて、次の値を定義します。
|
| lpName | LPWSTR | inoptional | 共有するリソースの名前。名前は MAX_PATH 文字に制限されます。名前の比較では大文字と小文字が区別されます。 ID3D11Device1::OpenSharedResourceByName メソッドを呼び出して共有リソースに名前でアクセスする場合は、リソース名が必要です。代わりに ID3D11Device1::OpenSharedResource1 メソッドを呼び出して共有リソースにハンドルでアクセスする場合は、このパラメーターを NULL に設定します。 lpName が既存のリソースの名前と一致する場合、CreateSharedHandle は DXGI_ERROR_NAME_ALREADY_EXISTS で失敗します。これらのオブジェクトは同じ名前空間を共有するため、この現象が発生します。 名前には "Global" または "Local" プレフィックスを付けて、グローバル名前空間またはセッション名前空間にオブジェクトを明示的に作成できます。名前の残りの部分には、バックスラッシュ文字(\)を除く任意の文字を含めることができます。詳細については、 Kernel Object Namespaces を参照してください。高速ユーザー切り替えはターミナルサービスセッションを使用して実装されています。アプリケーションが複数のユーザーをサポートできるように、カーネルオブジェクト名はターミナルサービス向けに示されたガイドラインに従う必要があります。 オブジェクトはプライベート名前空間に作成できます。詳細については、Object Namespaces を参照してください。 |
| pHandle | HANDLE* | out | 共有するリソースへの NT HANDLE 値を受け取る変数へのポインター。 このハンドルはリソースにアクセスするための呼び出しで使用できます。 |
戻り値
成功した場合は S_OK を返します。それ以外の場合は、次のいずれかの値を返します。
- パラメーターのいずれかが無効な場合は DXGI_ERROR_INVALID_CALL。
- 指定された共有リソースの名前が既に別のリソースに関連付けられている場合は DXGI_ERROR_NAME_ALREADY_EXISTS。
- 保護された名前空間にオブジェクトが作成されている場合は E_ACCESSDENIED。
- ハンドルを作成するのに十分なメモリがない場合は E_OUTOFMEMORY。
- その他、DXGI_ERROR トピックで説明されているエラーコードが返される可能性があります。
解説(Remarks)
CreateSharedHandle が NT ハンドルを返すのは、リソースを共有として作成し、NT ハンドルを使用することを指定した場合(つまり D3D11_RESOURCE_MISC_SHARED_NTHANDLE フラグと D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX フラグを設定した場合)のみです。リソースを共有として作成し、NT ハンドルを使用することを指定した場合は、共有用のハンドルを取得するために CreateSharedHandle を使用する必要があります。 この状況では、IDXGIResource::GetSharedHandle メソッドは失敗するため使用できません。
CreateSharedHandle が返すハンドルを ID3D11Device1::OpenSharedResource1 メソッドの呼び出しに渡すことで、別のデバイスで作成した共有リソースへのアクセス権をデバイスに与えることができます。
CreateSharedHandle が返すハンドルは NT ハンドルであるため、CloseHandle、DuplicateHandle などでハンドルを使用できます。CreateSharedHandle は共有リソースに対して 1 回だけ呼び出すことができ、以降の呼び出しは失敗します。 同じ共有リソースへのハンドルがさらに必要な場合は、DuplicateHandle を呼び出します。共有リソースハンドルが不要になったら、メモリリークを避けるために CloseHandle を呼び出してハンドルを閉じます。
リソースを共有するために CreateSharedHandle を呼び出すときに lpName にリソースの名前を渡した場合、後でこの名前を ID3D11Device1::OpenSharedResourceByName メソッドの呼び出しに渡すことで、別のデバイスに共有リソースへのアクセス権を与えることができます。名前付きリソースを使用すると、悪意のあるユーザーがこの名前付きリソースを先に使用し、アプリの起動を妨げる可能性があります。この状況を防ぐには、ランダムな名前のリソースを作成し、その名前を認可されたユーザーだけが取得できるように保存します。あるいは、この目的でファイルを使用することもできます。アプリをユーザーごとに 1 つのインスタンスに制限するには、ユーザーのプロファイルディレクトリにロックされたファイルを作成します。
リソースを共有として作成し、NT ハンドルを使用することを指定しなかった場合、CreateSharedHandle は失敗するため、共有用のハンドルを取得するために CreateSharedHandle を使用することはできません。
Examples
ID3D11Texture2D* pTexture2D;
ID3D11Device* pDevice;
pDevice->CreateTexture2D(…, &pTexture2D); // Create the texture as shared with NT HANDLEs.
HANDLE handle;
IDXGIResource1* pResource;
pTexture2D->QueryInterface(__uuidof(IDXGIResource1), (void**) &pResource);
pResource->CreateSharedHandle(NULL,
DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
NULL,
&handle);
// Pass the handle to another process to share the resource.
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IDXGIResource1 "{30961379-4609-4A41-998E-54FE567EE0C1}" #usecom global IDXGIResource1 IID_IDXGIResource1 "{}" #comfunc global IDXGIResource1_CreateSubresourceSurface 12 int,sptr #comfunc global IDXGIResource1_CreateSharedHandle 13 var,int,wstr,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IDXGIResource1 "{30961379-4609-4A41-998E-54FE567EE0C1}" #usecom global IDXGIResource1 IID_IDXGIResource1 "{}" #comfunc global IDXGIResource1_CreateSubresourceSurface 12 int,sptr #comfunc global IDXGIResource1_CreateSharedHandle 13 sptr,int,wstr,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。