d3d:d3d12:query
文書の過去の版を表示しています。
Direct3D 12 Query
Query の使い方
- ID3D12Device CreateQueryHeap (複数まとめて確保可能)
- ID3D12Device CreateResource (Resolve バッファ) D3D12_HEAP_TYPE_READBACK
- ID3D12CommandList BeginQuery, EndQuery
- ID3D12CommandList ResolveQueryData
- ID3D12Resource Map (読み出し)
Query を使った Timestamp の例
初期化
typedef unsigned long long UI64; unsigned int Offset= 0; constexpr unsigned int FRAME_COUNT= 4; constexpr unsigned int QUERY_COUNT= 2; ID3D12QueryHeap* iQuery= nullptr; ID3D12Resource* iBuffer= nullptr; { D3D12_QUERY_HEAP_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.Type= D3D12_QUERY_HEAP_TYPE_TIMESTAMP; desc.Count= QUERY_COUNT * FRAME_COUNT; iD3D12Device->CreateQueryHeap( &desc, IID_PPV_ARGS(&iQuery) ); } { D3D12_RESOURCE_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.SampleDesc.Count= 1; desc.Dimension= D3D12_RESOURCE_DIMENSION_BUFFER; desc.Width= sizeof(UI64) * QUERY_COUNT * FRAME_COUNT; desc.Height= 1; desc.MipLevels= 1; desc.DepthOrArraySize= 1; desc.Layout= D3D12_TEXTURE_LAYOUT_ROW_MAJOR; D3D12_HEAP_PROPERTIES heap; memset( &heap, 0, sizeof(heap) ); heap.Type= D3D12_HEAP_TYPE_READBACK; iD3D12Device->CreateCommittedResource( &heap, 0, D3D12_RESOURCE_STATE_COPY_DEST, IID_PPV_ARGS(&iBuffer) ); } iD3D12Device->SetStablePowerState( true );
描画と計測
ID3D12GraphcisCommandList* iCommand; ~ iCommand->EndQuery( iQuery, D3D12_QUERY_TYPE_TIMESTAMP, Offset + 0 ); // BeginQuery ではなく EndQuery で正しい ~ Draw など iCommand->EndQuery( iQuery, D3D12_QUERY_TYPE_TIMESTAMP, Offset + 1 ); iCommand->ResolveQueryData( iQuery, D3D12_QUERY_TYPE_TIMESTAMP, Offset, 2, iBuffer, Offset * sizeof(UI64) ); ~ UI64 GPU_Freq= 0; iCommandQueue->GetTimestampFrequency( &GPU_Freq ); { unsigned int offset= Offset + QUERY_COUNT; if( offset >= FRAME_COUNT * QUERY_COUNT ){ offset= 0; } Offset= offset; }
読み出し
unsigned int start= QUERY_COUNT * sizeof(UI64) * Offset; D3D12_RANGE range{ start, start + QUERY_COUNT * sizeof(UI64) }; void* ptr= nullptr; iBuffer->Map( 0, &range, &ptr ); auto data= reinterpret_cast<UI64*>( ptr ); float time_ms= (data[1] - data[0]) * 1000.0f / GPU_Freq; // 計測時間 ms iBuffer->Unmap( 0, nullptr );
注意点
最近の GPU は他の描画とオーバーラップ実行されることが多く、必ずしも Command 実行時の TimeStamp が正確な描画にかかった GPU 時間を計測しているとは限りません。単なる Command 発行間隔の計測になっている可能性があります。バッファが多ければ極端に短い結果を返す可能性があります。
d3d/d3d12/query.1441807386.txt.gz · 最終更新: 2015/09/09 23:03 by oga