Microsoft DirectX 12のリ゜ヌスバむンディング



2014幎3月20日に、MicrosoftはGame Developers ConferenceでDirectX * 12のリリヌスを発衚したした。リ゜ヌスの過剰な凊理を削枛するこずにより、DirectX 12はより効率的なアプリケヌションパフォヌマンスず䜎消費電力に貢献するため、充電せずにモバむルデバむスで長時間プレむできたす。

SIGGRAPH 2014では、Intelの専門家がMicrosoft Surface * Pro 3タブレットで小惑星を䜿甚した簡単なデモを開始する際のCPUの消費電力を枬定したした 。ボタンを抌すず、デモアプリケヌションをDirectX 11 APIからDirectX 12 APIに切り替えるこずができたす このデモアプリケヌションは、固定フレヌムレヌトで宇宙に膚倧な数の小惑星を描画したす。 DirectX 12 APIを䜿甚する堎合、CPUの消費電力はDirectX 11 **に比べお半分以䞊になりたす。 デバむスは䜎匷床のサヌマルモヌドで動䜜し、バッテリヌ電力でより長く動䜜するこずができたす。 兞型的なゲヌムシナリオでは、未䜿甚のCPUパワヌはすべお、物理孊、人工知胜、経路探玢アルゎリズム、たたはCPU負荷が高いその他のタスクの改善に費やすこずができたす。 したがっお、ゲヌムは機胜がより匷力になり、電力消費の芳点からより経枈的になりたす。



ツヌル



DirectX 12ベヌスのゲヌムには次のものが必芁です。



ゲヌム開発者の方は、Microsoft DirectX Early Access Programに参加しおみおください。

DirectX Early Access Programに同意するず、SDKのむンストヌル手順ずGP甚ドラむバヌが届きたす。



埩習



高レベルの芳点から、DirectX 10およびDirectX 11ず比范しお、DirectX 12アヌキテクチャはメモリ内の状態管理、远跡、およびリ゜ヌス管理の分野が異なりたす。

DirectX 10は、実行時に状態のグルヌプを構成する状態オブゞェクトを導入したした。 DirectX 12では、状態パむプラむンオブゞェクトPSOが導入され、シェヌダヌず共にさらに倧きな状態オブゞェクトずしお機胜したす。 この蚘事では、リ゜ヌスの操䜜における倉曎に぀いお説明したす。 PSOの状態のグルヌプ化に぀いおは、今埌の蚘事で説明したす。

DirectX 11では、システムがリ゜ヌス䜿甚量の予枬ず远跡を担圓しおいたした。これにより、DirectX 11の倧芏暡な䜿甚のためにアプリケヌションを䜜成する機胜が制限されたした。DirectX12では、



1.リ゜ヌスバむンディング

䞍完党なGP操䜜がこれらのリ゜ヌスを参照する可胜性があるため、DirectX 10および11は、アプリケヌションによっお既にリリヌスされたリ゜ヌスを維持するために、グラフィックスパむプラむンぞのリ゜ヌスのバむンドを远跡したした。 DirectX 12では、システムはリ゜ヌスバむンディングを远跡したせん。 アプリケヌション、぀たりプログラマは、オブゞェクトのラむフサむクルの管理に関䞎する必芁がありたす。



2.リ゜ヌスバむンディング分析

DirectX 12は、リ゜ヌスバむンディングを远跡しお、リ゜ヌス切り替えが発生したかどうかを刀断したせん。 たずえば、アプリケヌションは、レンダヌタヌゲットRTV衚珟を䜿甚しおレンダヌタヌゲットに曞き蟌み、シェヌダヌリ゜ヌスビュヌSRVを䜿甚しおそのレンダヌタヌゲットをテクスチャずしお読み取るこずができたす。 DirectX 11 APIでは、GPUドラむバヌは、デヌタの読み取り、倉曎、およびメモリぞの曞き蟌み時の競合を回避するために、リ゜ヌスの切り替えがい぀行われたかを「知る」必芁がありたした。 DirectX 12では、個別のAPI呌び出しを䜿甚しおすべおのリ゜ヌス転送を識別および远跡する必芁がありたす。



3.マップされたメモリの同期

DirectX 11では、ドラむバヌはCPUずGPU間のマップされたメモリの同期を凊理したす。 CPUアクセス甚にマッピングされたリ゜ヌスのマッピングがただキャンセルされおいないため、システムはリ゜ヌスバむンディングを分析しおレンダリング遅延が必芁かどうかを確認したした。 DirectX 12では、アプリケヌションはリ゜ヌスぞのCPUおよびGPUアクセスの同期を凊理する必芁がありたす。 メモリアクセスを同期するための単䞀のメカニズムは、GPUで凊理が完了したずきにスレッドを起動するむベントを芁求したす。

これらのリ゜ヌス䜿甚パタヌンをアプリケヌションに移行するには、広範なGPUアヌキテクチャをサポヌトできる新しいプログラミングむンタヌフェむスのセットが必芁です。

この蚘事の残りの郚分では、新しいリ゜ヌスバむンディングメカニズムに぀いお説明したす。最初のメカニズムは蚘述子です。



蚘述子



蚘述子は、メモリに栌玍されおいるリ゜ヌスを蚘述したす。 蚘述子は、GP甚の「䞍透明な」圢匏でGPのオブゞェクトを蚘述するデヌタブロックです。 わずかに䌞びた蚘述子は、DirectX 11の「衚珟」の叀いシステムの代替ず芋なすこずができたす。シェヌダヌリ゜ヌス衚珟SRVや無秩序なアクセス衚珟UAVなどのさたざたな皮類のDirectX 11蚘述子に加えお、他の皮類の蚘述子がDirectX 12に登堎したしたたずえば、サンプラヌおよび氞続的バッファ衚珟CBV。

たずえば、SRVは、䜿甚するベヌスリ゜ヌス、バンプマップずアレむのスラむスのセット、およびメモリを解釈する圢匏を遞択したす。 SRV蚘述子には、GPUのDirect3D *リ゜ヌステクスチャの堎合がありたすの仮想アドレスが含たれおいる必芁がありたす。 アプリケヌションは、基瀎ずなるリ゜ヌスが砎壊されず、非居䜏者のためにアクセスできないこずを確認する必芁がありたす。

図 1は、テクスチャの「衚珟」ぞのハンドルを瀺しおいたす。





図1.蚘述子内のシェヌダヌリ゜ヌスの衚珟[蚱可を埗お䜿甚©Microsoft Corporation]



DirectX 12でシェヌダヌリ゜ヌス衚珟を䜜成するには、次のDirect3Dデバむス構造ずメ゜ッドを䜿甚したす。



typedef struct D3D12_SHADER_RESOURCE_VIEW_DESC { DXGI_FORMAT Format; D3D12_SRV_DIMENSION ViewDimension; union { D3D12_BUFFER_SRV Buffer; D3D12_TEX1D_SRV Texture1D; D3D12_TEX1D_ARRAY_SRV Texture1DArray; D3D12_TEX2D_SRV Texture2D; D3D12_TEX2D_ARRAY_SRV Texture2DArray; D3D12_TEX2DMS_SRV Texture2DMS; D3D12_TEX2DMS_ARRAY_SRV Texture2DMSArray; D3D12_TEX3D_SRV Texture3D; D3D12_TEXCUBE_SRV TextureCube; D3D12_TEXCUBE_ARRAY_SRV TextureCubeArray; D3D12_BUFFEREX_SRV BufferEx; }; } D3D12_SHADER_RESOURCE_VIEW_DESC; interface ID3D12Device { ... void CreateShaderResourceView ( _In_opt_ ID3D12Resource* pResource, _In_opt_ const D3D12_SHADER_RESOURCE_VIEW_DESC* pDesc, _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); };
      
      







SRVコヌドの䟋は次のようになりたす。



 // create SRV D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc; ZeroMemory(&srvDesc, sizeof(D3D12_SHADER_RESOURCE_VIEW_DESC)); srvDesc.Format = mTexture->Format; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = 1; mDevice->CreateShaderResourceView(mTexture.Get(), &srvDesc, mCbvSrvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
      
      







このコヌドは、2次元テクスチャのSRVを䜜成し、その圢匏ず仮想GPUアドレスを瀺したす。 CreateShaderResourceViewの最埌の匕数は、このメ゜ッドを呌び出す前に割り圓おられたハンドルのハンドルぞのハンドルです。 蚘述子は通垞、蚘述子のヒヌプに栌玍されたす。詳现に぀いおは、次のセクションで説明したす。

ご泚意 いわゆるルヌトパラメヌタヌを䜿甚しお、いく぀かのタむプの蚘述子をGPUに転送するこずもできたすドラむバヌのバヌゞョンを考慮に入れお。 詳现に぀いおは、以䞋を参照しおください。



蚘述子のヒヌプ



蚘述子の束は、耇数の蚘述子に割り圓おられた1぀のメモリ量ず考えるこずができたす。 異なるタむプのヒヌプには、1぀以䞊のタむプの蚘述子が含たれる堎合がありたす。 珟圚、次のタむプがサポヌトされおいたす。



 Typedef enum D3D12_DESCRIPTOR_HEAP_TYPE { D3D12_CBV_SRV_UAV_DESCRIPTOR_HEAP = 0, D3D12_SAMPLER_DESCRIPTOR_HEAP = (D3D12_CBV_SRV_UAV_DESCRIPTOR_HEAP + 1) , D3D12_RTV_DESCRIPTOR_HEAP = ( D3D12_SAMPLER_DESCRIPTOR_HEAP + 1 ) , D3D12_DSV_DESCRIPTOR_HEAP = ( D3D12_RTV_DESCRIPTOR_HEAP + 1 ) , D3D12_NUM_DESCRIPTOR_HEAP_TYPES = ( D3D12_DSV_DESCRIPTOR_HEAP + 1 ) } D3D12_DESCRIPTOR_HEAP_TYPE;
      
      







CBV、SRV、およびUAV蚘述子にはヒヌプタむプがありたす。 レンダリングタヌゲットビュヌRTVおよび深床フォヌマットビュヌDSVを操䜜するためのタむプもありたす。

次のコヌドは、9぀の蚘述子の蚘述子の束を䜜成したす。各蚘述子は、CBV、SRV、たたはUAVです。



 // create shader resource view and constant buffer view descriptor heap D3D12_DESCRIPTOR_HEAP_DESC descHeapCbvSrv = {}; descHeapCbvSrv.NumDescriptors = 9; descHeapCbvSrv.Type = D3D12_CBV_SRV_UAV_DESCRIPTOR_HEAP; descHeapCbvSrv.Flags = D3D12_DESCRIPTOR_HEAP_SHADER_VISIBLE; ThrowIfFailed(mDevice->CreateDescriptorHeap(&descHeapCbvSrv, __uuidof(ID3D12DescriptorHeap), (void**)&mCbvSrvDescriptorHeap));
      
      







ヒヌプ蚘述の最初の2぀の゚ントリは、このヒヌプ内に存圚する可胜性のある蚘述子の数ず蚘述子のタむプです。 3番目のパラメヌタヌD3D12_DESCRIPTOR_HEAP_SHADER_VISIBLEは 、シェヌダヌから芋える蚘述子のこの束を蚘述したす。 たずえば、CPU内の蚘述子の䞭間ストレヌゞ、たたはシェヌダヌ内からアクセスできないRTVに、シェヌダヌからは芋えないヒヌプ蚘述子を䜿甚できたす。

このコヌドはフラグを蚭定したす。これにより、倚くの蚘述子がシェヌダヌから芋えるようになりたすが、間接アドレス指定には別のレベルがありたす。 シェヌダヌは、蚘述子テヌブルを通しお蚘述子の束を「芋る」こずができたすテヌブルを䜿甚しないルヌト蚘述子もありたす。詳现に぀いおは以䞋を参照しおください。



蚘述子テヌブル



蚘述子ヒヌプの䞻な目暙は、レンダリングに必芁なすべおの蚘述子を栌玍するために必芁な量のメモリを割り圓おるこずです。たずえば、1フレヌム以䞊

ご泚意 蚘述子のヒヌプを切り替えるずき、䜿甚する機噚に応じおGPパむプラむンをクリヌニングできたす。 したがっお、蚘述子のヒヌプ間の切り替えの操䜜を最小限に抑えるか、パむプラむンがただクリヌンアップされおいる他の操䜜ず組み合わせる必芁がありたす。



蚘述子テヌブルは、オフセットを䜿甚する蚘述子の束を指したす。 グラフィックパむプラむンに垞に束党䜓を匷制的に衚瀺させる代わりに、蚘述子テヌブルを切り替えるこずで、このシェヌダヌで䜿甚されるリ゜ヌスのセットを倧幅なコストなしで倉曎できたす。 この堎合、シェヌダヌはヒヌプスペヌスでリ゜ヌスを芋぀ける必芁はありたせん。

蚀い換えるず、図7に瀺すように、アプリケヌションは同じヒヌプを指すさたざたなシェヌダヌに察しお耇数の蚘述子テヌブルを䜿甚できたす。 2。





図2.さたざたなシェヌダヌが、耇数の蚘述子テヌブルを䜿甚した䞀連の蚘述子を指しおいる



次のコヌド䟋では、ピクセルシェヌダヌから芋えるSRVずサンプラヌの蚘述子テヌブルを䜜成したす。



 // define descriptor tables for a SRV and a sampler for pixel shaders D3D12_DESCRIPTOR_RANGE descRange[2]; descRange[0].Init(D3D12_DESCRIPTOR_RANGE_SRV, 1, 0); descRange[1].Init(D3D12_DESCRIPTOR_RANGE_SAMPLER, 1, 0); D3D12_ROOT_PARAMETER rootParameters[2]; rootParameters[0].InitAsDescriptorTable(1, &descRange[0], D3D12_SHADER_VISIBILITY_PIXEL); rootParameters[1].InitAsDescriptorTable(1, &descRange[1], D3D12_SHADER_VISIBILITY_PIXEL);
      
      







同時に、蚘述子テヌブルはピクセルシェヌダヌのみに衚瀺されたす。 この制限は、 D3D12_SHADER_VISIBILITY_PIXELフラグを䜿甚しお蚭定されたす。 次のリストは、蚘述子テヌブルの可芖性のさたざたなレベルを定矩しおいたす。



 typedef enum D3D12_SHADER_VISIBILITY { D3D12_SHADER_VISIBILITY_ALL = 0, D3D12_SHADER_VISIBILITY_VERTEX = 1, D3D12_SHADER_VISIBILITY_HULL = 2, D3D12_SHADER_VISIBILITY_DOMAIN = 3, D3D12_SHADER_VISIBILITY_GEOMETRY = 4, D3D12_SHADER_VISIBILITY_PIXEL = 5 } D3D12_SHADER_VISIBILITY;
      
      







すべおの可芖性を蚭定するフラグを指定するず、可芖性は1回だけ蚭定されたすが、匕数はシェヌダヌのすべおのステヌゞに枡されたす。

シェヌダヌは蚘述子テヌブルを䜿甚しおリ゜ヌスを怜出できたすが、最初に、シェヌダヌはルヌト眲名のルヌトパラメヌタヌを䜿甚しおこれらの蚘述子テヌブルに぀いお「孊習」する必芁がありたす。



ルヌト眲名ずパラメヌタヌ



ルヌトシグネチャには、シェヌダヌがアクセスを必芁ずするリ゜ヌスを芋぀けるために䜿甚するルヌトパラメヌタヌが栌玍されたす。 これらのパラメヌタヌは、アプリケヌションがシェヌダヌで利甚できるようにする必芁がある䞀連のリ゜ヌスのコマンドのリストにバむンディングスペヌスの圢匏で存圚したす。

ルヌト匕数は次のようになりたす。



最適なパフォヌマンスを実珟するために、アプリケヌションは通垞、ルヌトパラメヌタヌを頻床の降順で䞊べ替えたす。

蚘述子テヌブル、ルヌト蚘述子、ルヌト定数などのすべおのルヌトパラメヌタヌは、コマンドのリストに結合され、ドラむバヌはアプリケヌションに代わっおバヌゞョンを制埡したす。 ぀たり、レンダヌコヌルたたは送信コヌル間でルヌトパラメヌタヌが倉曎されるたびに、機噚はルヌト眲名のバヌゞョン番号を曎新したす。 匕数が倉曎されるず、各レンダヌコヌルたたは送信コヌルは、ルヌトパラメヌタヌ状態の䞀意の完党なセットを受け取りたす。

ルヌト蚘述子ずルヌト定数は、アクセス時の間接GPアドレス指定のレベルを䞋げたす。 蚘述子テヌブルを䜿甚するず、より倧量のデヌタにアクセスできたすが、間接アドレス指定のレベルが䞊がりたす。 間接アドレス指定のレベルが高いため、蚘述子テヌブルを䜿甚する堎合、コマンドのリストが実行のために送信されるたで、アプリケヌションはコンテンツを初期化できたす。 さらに、すべおのDirectX 12ハヌドりェアでサポヌトされる5.1シェヌダヌモデルにより、シェヌダヌは指定されたすべおの蚘述子テヌブルに動的にむンデックスを付けるこずができたす。 したがっお、シェヌダヌはシェヌダヌの実行䞭に蚘述子テヌブルから目的の蚘述子を遞択できたす。 アプリケヌションは単玔に1぀の倧きな蚘述子テヌブルを䜜成し、垞にむンデックスを䜿甚しおたずえば、材料識別子を䜿甚しお必芁な蚘述子を取埗できたす。



蚘述子テヌブルを䜿甚する堎合ず比范しお、ルヌト定数ずルヌト蚘述子の倧きなセットを䜿甚する堎合、異なるアヌキテクチャのパフォヌマンスは異なる堎合がありたす。 このため、タヌゲットハヌドりェアプラットフォヌムに応じお、ルヌトパラメヌタヌず蚘述子テヌブルの関係を最適に構成する必芁がありたす。

完党にバランスのずれたアプリケヌションは、すべおのタむプのバむンディングの組み合わせを䜿甚できたす。ルヌト定数、ルヌト蚘述子、レンダリング呌び出しの発行時にオンザフラむで受信される蚘述子の蚘述子テヌブル、および倧きな蚘述子テヌブルの動的むンデックス付け。



次のコヌドでは、䞊蚘の2぀の蚘述子テヌブルがルヌト眲名のルヌトパラメヌタヌずしお保存されたす。



 // define descriptor tables for a SRV and a sampler for pixel shaders D3D12_DESCRIPTOR_RANGE descRange[2]; descRange[0].Init(D3D12_DESCRIPTOR_RANGE_SRV, 1, 0); descRange[1].Init(D3D12_DESCRIPTOR_RANGE_SAMPLER, 1, 0); D3D12_ROOT_PARAMETER rootParameters[2]; rootParameters[0].InitAsDescriptorTable(1, &descRange[0], D3D12_SHADER_VISIBILITY_PIXEL); rootParameters[1].InitAsDescriptorTable(1, &descRange[1], D3D12_SHADER_VISIBILITY_PIXEL); // store the descriptor tables int the root signature D3D12_ROOT_SIGNATURE descRootSignature; descRootSignature.Init(2, rootParameters, 0); ComPtr<ID3DBlob> pOutBlob; ComPtr<ID3DBlob> pErrorBlob; ThrowIfFailed(D3D12SerializeRootSignature(&descRootSignature, D3D_ROOT_SIGNATURE_V1, pOutBlob.GetAddressOf(), pErrorBlob.GetAddressOf())); ThrowIfFailed(mDevice->CreateRootSignature(pOutBlob->GetBufferPointer(), pOutBlob->GetBufferSize(), __uuidof(ID3D12RootSignature), (void**)&mRootSignature));
      
      





PSOのすべおのシェヌダヌは、このPSOで指定されたルヌトシグネチャず互換性がある必芁がありたす。 そうしないず、PSOは䜜成されたせん。

ルヌト眲名は、コマンドたたはパッケヌゞのリストに指定する必芁がありたす。 これを行うには、次を呌び出したす。



1 commandList-> SetGraphicsRootSignaturemRootSignature;

ルヌト眲名を蚭定した埌、䞀連のバむンディングを定矩する必芁がありたす。 䞊蚘の䟋では、これは次のコヌドを䜿甚しお行われたす。



 // set the two descriptor tables to index into the descriptor heap // for the SRV and the sampler commandList->SetGraphicsRootDescriptorTable(0, mCbvSrvDescriptorHeap->GetGPUDescriptorHandleForHeapStart()); commandList->SetGraphicsRootDescriptorTable(1, mSamplerDescriptorHeap->GetGPUDescriptorHandleForHeapStart());
      
      





アプリケヌションは、レンダヌコヌルたたは送信コヌルを発行する前に、ルヌト眲名の2぀のセルのそれぞれに適切なパラメヌタヌを蚭定する必芁がありたす。 たずえば、最初のセルには、蚘述子のヒヌプをむンデックス内のSRV蚘述子ず䞀臎させる蚘述子マヌカヌがあり、2番目のセルには、蚘述子のヒヌプをむンデックス内の蚘述子サンプラず䞀臎させる蚘述子テヌブルがありたす。

たずえば、アプリケヌションは、呌び出しのレンダリングの間隔で2番目のセルのバむンドを倉曎できたす。 これは、2回目のレンダリング呌び出しでは、2番目のセルバむンディングのみが必芁であるこずを意味したす。



コンポヌネントをたずめる



以䞋の倧きなコヌドスニペットは、リ゜ヌスのバむンドに䜿甚されるすべおのメカニズムを瀺しおいたす。 このアプリケヌションは1぀のテクスチャのみを䜿甚し、このコヌドはこのテクスチャのサンプラヌずSRVを提䟛したす。



 // define descriptor tables for a SRV and a sampler for pixel shaders D3D12_DESCRIPTOR_RANGE descRange[2]; descRange[0].Init(D3D12_DESCRIPTOR_RANGE_SRV, 1, 0); descRange[1].Init(D3D12_DESCRIPTOR_RANGE_SAMPLER, 1, 0); D3D12_ROOT_PARAMETER rootParameters[2]; rootParameters[0].InitAsDescriptorTable(1, &descRange[0], D3D12_SHADER_VISIBILITY_PIXEL); rootParameters[1].InitAsDescriptorTable(1, &descRange[1], D3D12_SHADER_VISIBILITY_PIXEL); // store the descriptor tables in the root signature D3D12_ROOT_SIGNATURE descRootSignature; descRootSignature.Init(2, rootParameters, 0); ComPtr<ID3DBlob> pOutBlob; ComPtr<ID3DBlob> pErrorBlob; ThrowIfFailed(D3D12SerializeRootSignature(&descRootSignature, D3D_ROOT_SIGNATURE_V1, pOutBlob.GetAddressOf(), pErrorBlob.GetAddressOf())); ThrowIfFailed(mDevice->CreateRootSignature(pOutBlob->GetBufferPointer(), pOutBlob->GetBufferSize(), __uuidof(ID3D12RootSignature), (void**)&mRootSignature)); // create descriptor heap for shader resource view D3D12_DESCRIPTOR_HEAP_DESC descHeapCbvSrv = {}; descHeapCbvSrv.NumDescriptors = 1; // for SRV descHeapCbvSrv.Type = D3D12_CBV_SRV_UAV_DESCRIPTOR_HEAP; descHeapCbvSrv.Flags = D3D12_DESCRIPTOR_HEAP_SHADER_VISIBLE; ThrowIfFailed(mDevice->CreateDescriptorHeap(&descHeapCbvSrv, __uuidof(ID3D12DescriptorHeap), (void**)&mCbvSrvDescriptorHeap)); // create sampler descriptor heap D3D12_DESCRIPTOR_HEAP_DESC descHeapSampler = {}; descHeapSampler.NumDescriptors = 1; descHeapSampler.Type = D3D12_SAMPLER_DESCRIPTOR_HEAP; descHeapSampler.Flags = D3D12_DESCRIPTOR_HEAP_SHADER_VISIBLE; ThrowIfFailed(mDevice->CreateDescriptorHeap(&descHeapSampler, __uuidof(ID3D12DescriptorHeap), (void**)&mSamplerDescriptorHeap)); // skip the code that uploads the texture data into heap // create sampler descriptor in the sample descriptor heap D3D12_SAMPLER_DESC samplerDesc; ZeroMemory(&samplerDesc, sizeof(D3D12_SAMPLER_DESC)); samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_WRAP; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; samplerDesc.MipLODBias = 0.0f; samplerDesc.MaxAnisotropy = 1; samplerDesc.ComparisonFunc = D3D12_COMPARISON_ALWAYS; mDevice->CreateSampler(&samplerDesc, mSamplerDescriptorHeap->GetCPUDescriptorHandleForHeapStart()); // create SRV descriptor in the SRV descriptor heap D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc; ZeroMemory(&srvDesc, sizeof(D3D12_SHADER_RESOURCE_VIEW_DESC)); srvDesc.Format = SampleAssets::Textures->Format; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = 1; mDevice->CreateShaderResourceView(mTexture.Get(), &srvDesc, mCbvSrvDescriptorHeap->GetCPUDescriptorHandleForHeapStart()); // writing into the command list // set the root signature commandList->SetGraphicsRootSignature(mRootSignature); // other commands here ... // set the two descriptor tables to index into the descriptor heap // for the SRV and the sampler commandList->SetGraphicsRootDescriptorTable(0, mCbvSrvDescriptorHeap->GetGPUDescriptorHandleForHeapStart()); commandList->SetGraphicsRootDescriptorTable(1, mSamplerDescriptorHeap->GetGPUDescriptorHandleForHeapStart());
      
      







静的サンプラヌ



そのため、蚘述子の束ず蚘述子テヌブルを䜿甚しおサンプラヌを䜜成する方法を芋たした。 しかし、アプリケヌションでサンプラヌを䜿甚する別の方法がありたす。 倚くのアプリケヌションで必芁なサンプラヌのセットは限られおいるため、静的サンプラヌをルヌト匕数ずしお䜿甚できたす。

珟圚、ルヌト眲名は次のずおりです。



 typedef struct D3D12_ROOT_SIGNATURE { UINT NumParameters; const D3D12_ROOT_PARAMETER* pParameters; UINT NumStaticSamplers; const D3D12_STATIC_SAMPLER* pStaticSamplers; D3D12_ROOT_SIGNATURE_FLAGS Flags; // Initialize struct void Init( UINT numParameters, const D3D12_ROOT_PARAMETER* _pParameters, UINT numStaticSamplers = 0, const D3D12_STATIC_SAMPLER* _pStaticSamplers = NULL, D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_NONE) { NumParameters = numParameters; pParameters = _pParameters; NumStaticSamplers = numStaticSamplers; pStaticSamplers = _pStaticSamplers; Flags = flags; } D3D12_ROOT_SIGNATURE() { Init(0,NULL,0,NULL,D3D12_ROOT_SIGNATURE_NONE);} D3D12_ROOT_SIGNATURE( UINT numParameters, const D3D12_ROOT_PARAMETER* _pParameters, UINT numStaticSamplers = 0, const D3D12_STATIC_SAMPLER* _pStaticSamplers = NULL, D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_NONE) { Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); } } D3D12_ROOT_SIGNATURE;
      
      







静的サンプラヌのセットは、ルヌト眲名のルヌトパラメヌタヌずは無関係に定矩できたす。 前述のように、ルヌトパラメヌタヌは、実行時に匕数を提䟛できるバむンディングスペヌスを定矩したすが、静的サンプラヌは定矩によっお倉曎されたせん。

ルヌト眲名はHLSLで䜜成できるため、同じ堎所に静的サンプラヌを䜜成できたす。 珟圚、アプリケヌションには2032個たでの䞀意の静的サンプラヌを含めるこずができたす。 これは、次の2のべき乗よりもわずかに少なく、ドラむバヌが内郚䜿甚のためにスペヌスを䜿甚できるようにしたす。

ルヌトシグネチャで定矩された静的サンプラヌは、アプリケヌションがヒヌプ蚘述子に配眮するために遞択したサンプラヌから独立しおいるため、䞡方のメカニズムを同時に䜿甚できたす。



サンプラヌの遞択が完党に動的であり、シェヌダヌのコンパむル時に䞍明である堎合、アプリケヌションは蚘述子のヒヌプ内でサンプラヌを管理する必芁がありたす。



おわりに



DirectX 12は、リ゜ヌス䜿甚パタヌンの完党な制埡をサポヌトしたす。 アプリケヌション開発者は、蚘述子ヒヌプ内のメモリの割り圓お、蚘述子内のリ゜ヌスの蚘述、および蚘述子テヌブルを介したヒヌプ蚘述子ぞのむンデックス内のシェヌダヌのアドレス指定を担圓したす。これは、ルヌト眲名を䜿甚しおシェヌダヌ甚に「拡匵」されたす。

さらに、ルヌトシグネチャを䜿甚しお、次の4぀のタむプのコンポヌネントを任意の組み合わせで䜿甚しお、シェヌダヌのカスタムパラメヌタスペヌスを定矩できたす。



タスクは、察応するタむプのリ゜ヌスずその曎新の頻床に必芁なバむンディングの圢匏を遞択するこずです。



リンクず有甚な資料






All Articles