mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
D3D12: Added pipeline stats. (#3534)
This commit is contained in:
committed by
GitHub
parent
80370936d0
commit
d9d99f51ad
@@ -656,6 +656,8 @@ namespace bgfx { namespace d3d12
|
||||
}
|
||||
}
|
||||
|
||||
typedef HRESULT (WINAPI* PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES)(uint32_t _numFeatures, const IID* _iids, void* _configurationStructs, uint32_t* _configurationStructSizes);
|
||||
|
||||
#if USE_D3D12_DYNAMIC_LIB
|
||||
static PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES D3D12EnableExperimentalFeatures;
|
||||
static PFN_D3D12_CREATE_DEVICE D3D12CreateDevice;
|
||||
@@ -4108,22 +4110,25 @@ namespace bgfx { namespace d3d12
|
||||
queueDesc.Priority = 0;
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.NodeMask = 1;
|
||||
DX_CHECK(_device->CreateCommandQueue(&queueDesc
|
||||
DX_CHECK(_device->CreateCommandQueue(
|
||||
&queueDesc
|
||||
, IID_ID3D12CommandQueue
|
||||
, (void**)&m_commandQueue
|
||||
) );
|
||||
|
||||
m_completedFence = 0;
|
||||
m_currentFence = 0;
|
||||
DX_CHECK(_device->CreateFence(0
|
||||
DX_CHECK(_device->CreateFence(
|
||||
0
|
||||
, D3D12_FENCE_FLAG_NONE
|
||||
, IID_ID3D12Fence
|
||||
, (void**)&m_fence
|
||||
) );
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_commandList); ++ii)
|
||||
for (uint32_t ii = 0; ii < kMaxCommandLists; ++ii)
|
||||
{
|
||||
DX_CHECK(_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT
|
||||
DX_CHECK(_device->CreateCommandAllocator(
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT
|
||||
, IID_ID3D12CommandAllocator
|
||||
, (void**)&m_commandList[ii].m_commandAllocator
|
||||
) );
|
||||
@@ -4138,6 +4143,30 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
DX_CHECK(m_commandList[ii].m_commandList->Close() );
|
||||
}
|
||||
|
||||
const D3D12_QUERY_HEAP_DESC queryHeapDesc =
|
||||
{
|
||||
.Type = D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS,
|
||||
.Count = kMaxCommandLists,
|
||||
.NodeMask = 1,
|
||||
};
|
||||
|
||||
DX_CHECK(_device->CreateQueryHeap(
|
||||
&queryHeapDesc
|
||||
, IID_ID3D12QueryHeap
|
||||
, (void**)&m_pipelineStatsQueryHeap
|
||||
) );
|
||||
setDebugObjectName(m_pipelineStatsQueryHeap, "Pipeline Statistics Query Heap");
|
||||
|
||||
m_pipelineStatsReadBack = createCommittedResource(_device, HeapProperty::ReadBack, kMaxCommandLists*sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS) );
|
||||
setDebugObjectName(m_pipelineStatsReadBack, "Pipeline Statistics Read-Back");
|
||||
|
||||
const D3D12_RANGE range =
|
||||
{
|
||||
.Begin = 0,
|
||||
.End = kMaxCommandLists*sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS),
|
||||
};
|
||||
m_pipelineStatsReadBack->Map(0, &range, (void**)&m_pipelineStats);
|
||||
}
|
||||
|
||||
void CommandQueueD3D12::shutdown()
|
||||
@@ -4146,13 +4175,22 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
DX_RELEASE(m_fence, 0);
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_commandList); ++ii)
|
||||
for (uint32_t ii = 0; ii < kMaxCommandLists; ++ii)
|
||||
{
|
||||
DX_RELEASE(m_commandList[ii].m_commandAllocator, 0);
|
||||
DX_RELEASE(m_commandList[ii].m_commandList, 0);
|
||||
}
|
||||
|
||||
DX_RELEASE(m_commandQueue, 0);
|
||||
|
||||
const D3D12_RANGE range =
|
||||
{
|
||||
.Begin = 0,
|
||||
.End = kMaxCommandLists*sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS),
|
||||
};
|
||||
m_pipelineStatsReadBack->Unmap(0, &range);
|
||||
DX_RELEASE(m_pipelineStatsQueryHeap, 0);
|
||||
DX_RELEASE(m_pipelineStatsReadBack, 0);
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* CommandQueueD3D12::alloc()
|
||||
@@ -4165,12 +4203,33 @@ namespace bgfx { namespace d3d12
|
||||
CommandList& commandList = m_commandList[m_control.m_current];
|
||||
DX_CHECK(commandList.m_commandAllocator->Reset() );
|
||||
DX_CHECK(commandList.m_commandList->Reset(commandList.m_commandAllocator, NULL) );
|
||||
commandList.m_commandList->BeginQuery(
|
||||
m_pipelineStatsQueryHeap
|
||||
, D3D12_QUERY_TYPE_PIPELINE_STATISTICS
|
||||
, m_control.m_current
|
||||
);
|
||||
return commandList.m_commandList;
|
||||
}
|
||||
|
||||
uint64_t CommandQueueD3D12::kick()
|
||||
{
|
||||
CommandList& commandList = m_commandList[m_control.m_current];
|
||||
const uint32_t currentIdx = m_control.m_current;
|
||||
CommandList& commandList = m_commandList[currentIdx];
|
||||
|
||||
commandList.m_commandList->EndQuery(
|
||||
m_pipelineStatsQueryHeap
|
||||
, D3D12_QUERY_TYPE_PIPELINE_STATISTICS
|
||||
, currentIdx
|
||||
);
|
||||
commandList.m_commandList->ResolveQueryData(
|
||||
m_pipelineStatsQueryHeap
|
||||
, D3D12_QUERY_TYPE_PIPELINE_STATISTICS
|
||||
, currentIdx
|
||||
, 1
|
||||
, m_pipelineStatsReadBack
|
||||
, currentIdx*sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS)
|
||||
);
|
||||
|
||||
DX_CHECK(commandList.m_commandList->Close() );
|
||||
|
||||
ID3D12CommandList* commandLists[] = { commandList.m_commandList };
|
||||
@@ -4247,6 +4306,8 @@ namespace bgfx { namespace d3d12
|
||||
}
|
||||
ra.clear();
|
||||
|
||||
m_pipelineStatsSum.add(m_pipelineStats[m_control.m_read]);
|
||||
|
||||
m_control.consume(1);
|
||||
|
||||
return true;
|
||||
@@ -6138,24 +6199,32 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
void TimerQueryD3D12::init()
|
||||
{
|
||||
D3D12_QUERY_HEAP_DESC queryHeapDesc;
|
||||
queryHeapDesc.Count = m_control.m_size * 2;
|
||||
queryHeapDesc.NodeMask = 1;
|
||||
queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
|
||||
DX_CHECK(s_renderD3D12->m_device->CreateQueryHeap(&queryHeapDesc
|
||||
ID3D12Device* device = s_renderD3D12->m_device;
|
||||
|
||||
D3D12_QUERY_HEAP_DESC queryHeapDesc =
|
||||
{
|
||||
.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP,
|
||||
.Count = m_control.m_size * 2,
|
||||
.NodeMask = 1,
|
||||
};
|
||||
|
||||
DX_CHECK(device->CreateQueryHeap(
|
||||
&queryHeapDesc
|
||||
, IID_ID3D12QueryHeap
|
||||
, (void**)&m_queryHeap
|
||||
) );
|
||||
setDebugObjectName(m_queryHeap, "Timer Query Heap");
|
||||
|
||||
const uint32_t size = queryHeapDesc.Count*sizeof(uint64_t);
|
||||
m_readback = createCommittedResource(s_renderD3D12->m_device
|
||||
m_readback = createCommittedResource(device
|
||||
, HeapProperty::ReadBack
|
||||
, size
|
||||
);
|
||||
setDebugObjectName(m_readback, "Timer Query Read-Back");
|
||||
|
||||
DX_CHECK(s_renderD3D12->m_cmd.m_commandQueue->GetTimestampFrequency(&m_frequency) );
|
||||
|
||||
D3D12_RANGE range = { 0, size };
|
||||
D3D12_RANGE range = { .Begin = 0, .End = size };
|
||||
m_readback->Map(0, &range, (void**)&m_queryResult);
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_result); ++ii)
|
||||
@@ -6178,6 +6247,8 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
uint32_t TimerQueryD3D12::begin(uint32_t _resultIdx, uint32_t _frameNum)
|
||||
{
|
||||
ID3D12GraphicsCommandList* commandList = s_renderD3D12->m_commandList;
|
||||
|
||||
while (0 == m_control.reserve(1) )
|
||||
{
|
||||
m_control.consume(1);
|
||||
@@ -6192,8 +6263,6 @@ namespace bgfx { namespace d3d12
|
||||
query.m_ready = false;
|
||||
query.m_frameNum = _frameNum;
|
||||
|
||||
ID3D12GraphicsCommandList* commandList = s_renderD3D12->m_commandList;
|
||||
|
||||
uint32_t offset = idx * 2 + 0;
|
||||
commandList->EndQuery(m_queryHeap
|
||||
, D3D12_QUERY_TYPE_TIMESTAMP
|
||||
@@ -6207,13 +6276,13 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
void TimerQueryD3D12::end(uint32_t _idx)
|
||||
{
|
||||
ID3D12GraphicsCommandList* commandList = s_renderD3D12->m_commandList;
|
||||
|
||||
Query& query = m_query[_idx];
|
||||
query.m_ready = true;
|
||||
query.m_fence = s_renderD3D12->m_cmd.m_currentFence - 1;
|
||||
uint32_t offset = _idx * 2;
|
||||
|
||||
ID3D12GraphicsCommandList* commandList = s_renderD3D12->m_commandList;
|
||||
|
||||
commandList->EndQuery(m_queryHeap
|
||||
, D3D12_QUERY_TYPE_TIMESTAMP
|
||||
, offset + 1
|
||||
@@ -6276,10 +6345,11 @@ namespace bgfx { namespace d3d12
|
||||
) );
|
||||
|
||||
const uint32_t size = BX_COUNTOF(m_handle)*sizeof(uint64_t);
|
||||
m_readback = createCommittedResource(s_renderD3D12->m_device
|
||||
, HeapProperty::ReadBack
|
||||
, size
|
||||
);
|
||||
m_readback = createCommittedResource(
|
||||
s_renderD3D12->m_device
|
||||
, HeapProperty::ReadBack
|
||||
, size
|
||||
);
|
||||
|
||||
D3D12_RANGE range = { 0, size };
|
||||
m_readback->Map(0, &range, (void**)&m_result);
|
||||
@@ -6527,9 +6597,6 @@ namespace bgfx { namespace d3d12
|
||||
static ViewState viewState;
|
||||
viewState.reset(_render);
|
||||
|
||||
// bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);
|
||||
// setDebugWireframe(wireframe);
|
||||
|
||||
uint16_t currentSamplerStateIdx = kInvalidHandle;
|
||||
ProgramHandle currentProgram = BGFX_INVALID_HANDLE;
|
||||
uint32_t currentBindHash = 0;
|
||||
@@ -7389,7 +7456,6 @@ namespace bgfx { namespace d3d12
|
||||
{
|
||||
BGFX_D3D12_PROFILER_BEGIN_LITERAL("debugstats", kColorFrame);
|
||||
|
||||
// m_needPresent = true;
|
||||
TextVideoMem& tvm = m_textVideoMem;
|
||||
|
||||
static int64_t next = timeEnd;
|
||||
@@ -7548,6 +7614,17 @@ namespace bgfx { namespace d3d12
|
||||
);
|
||||
pos++;
|
||||
|
||||
tvm.printf(10, pos++, 0x8b, " Pipeline Statistics:");
|
||||
const CommandQueueD3D12::PipelineStats& pipelineStats = m_cmd.m_pipelineStatsSum;
|
||||
tvm.printf(10, pos++, 0x8b, " IAVertices: %llu", pipelineStats.IAVertices);
|
||||
tvm.printf(10, pos++, 0x8b, " IAPrimitives: %llu", pipelineStats.IAPrimitives);
|
||||
tvm.printf(10, pos++, 0x8b, " VSInvocations: %llu", pipelineStats.VSInvocations);
|
||||
tvm.printf(10, pos++, 0x8b, " CInvocations: %llu", pipelineStats.CInvocations);
|
||||
tvm.printf(10, pos++, 0x8b, " CPrimitives: %llu", pipelineStats.CPrimitives);
|
||||
tvm.printf(10, pos++, 0x8b, " PSInvocations: %llu", pipelineStats.PSInvocations);
|
||||
tvm.printf(10, pos++, 0x8b, " CSInvocations: %llu", pipelineStats.CSInvocations);
|
||||
pos++;
|
||||
|
||||
double captureMs = double(captureElapsed)*toMs;
|
||||
tvm.printf(10, pos++, 0x8b, " Capture: %7.4f [ms] ", captureMs);
|
||||
|
||||
@@ -7616,6 +7693,7 @@ namespace bgfx { namespace d3d12
|
||||
#endif // BX_PLATFORM_WINDOWS
|
||||
|
||||
m_backBufferColorFence[m_backBufferColorIdx] = kick();
|
||||
m_cmd.m_pipelineStatsSum.reset();
|
||||
}
|
||||
|
||||
} /* namespace d3d12 */ } // namespace bgfx
|
||||
|
||||
@@ -77,8 +77,6 @@ extern "C" uint64_t WINAPI bgfx_PIXEventsReplaceBlock(PIXEven
|
||||
|
||||
namespace bgfx { namespace d3d12
|
||||
{
|
||||
typedef HRESULT (WINAPI* PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES)(uint32_t _numFeatures, const IID* _iids, void* _configurationStructs, uint32_t* _configurationStructSizes);
|
||||
|
||||
struct Rdt
|
||||
{
|
||||
enum Enum
|
||||
@@ -372,6 +370,8 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
struct CommandQueueD3D12
|
||||
{
|
||||
static constexpr uint32_t kMaxCommandLists = 256;
|
||||
|
||||
CommandQueueD3D12()
|
||||
: m_currentFence(0)
|
||||
, m_completedFence(0)
|
||||
@@ -396,14 +396,57 @@ namespace bgfx { namespace d3d12
|
||||
HANDLE m_event;
|
||||
};
|
||||
|
||||
struct PipelineStats
|
||||
{
|
||||
PipelineStats()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
IAVertices = 0;
|
||||
IAPrimitives = 0;
|
||||
VSInvocations = 0;
|
||||
CInvocations = 0;
|
||||
CPrimitives = 0;
|
||||
PSInvocations = 0;
|
||||
CSInvocations = 0;
|
||||
}
|
||||
|
||||
void add(const D3D12_QUERY_DATA_PIPELINE_STATISTICS& _stats)
|
||||
{
|
||||
IAVertices += _stats.IAVertices;
|
||||
IAPrimitives += _stats.IAPrimitives;
|
||||
VSInvocations += _stats.VSInvocations;
|
||||
CInvocations += _stats.CInvocations;
|
||||
CPrimitives += _stats.CPrimitives;
|
||||
PSInvocations += _stats.PSInvocations;
|
||||
CSInvocations += _stats.CSInvocations;
|
||||
}
|
||||
|
||||
uint64_t IAVertices;
|
||||
uint64_t IAPrimitives;
|
||||
uint64_t VSInvocations;
|
||||
uint64_t CInvocations;
|
||||
uint64_t CPrimitives;
|
||||
uint64_t PSInvocations;
|
||||
uint64_t CSInvocations;
|
||||
};
|
||||
|
||||
ID3D12CommandQueue* m_commandQueue;
|
||||
uint64_t m_currentFence;
|
||||
uint64_t m_completedFence;
|
||||
ID3D12Fence* m_fence;
|
||||
CommandList m_commandList[256];
|
||||
CommandList m_commandList[kMaxCommandLists];
|
||||
typedef stl::vector<ID3D12Resource*> ResourceArray;
|
||||
ResourceArray m_release[256];
|
||||
ResourceArray m_release[kMaxCommandLists];
|
||||
bx::RingBufferControl m_control;
|
||||
|
||||
ID3D12Resource* m_pipelineStatsReadBack;
|
||||
ID3D12QueryHeap* m_pipelineStatsQueryHeap;
|
||||
D3D12_QUERY_DATA_PIPELINE_STATISTICS* m_pipelineStats;
|
||||
PipelineStats m_pipelineStatsSum;
|
||||
};
|
||||
|
||||
struct BatchD3D12
|
||||
|
||||
Reference in New Issue
Block a user