mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2025-02-17 20:31:57 -05:00
D3D12: Added occlusion query support.
This commit is contained in:
parent
c0b62332d7
commit
a9099f6b28
2 changed files with 129 additions and 2 deletions
|
@ -364,6 +364,7 @@ namespace bgfx { namespace d3d12
|
||||||
static const GUID IID_ID3D12PipelineState = { 0x765a30f3, 0xf624, 0x4c6f, { 0xa8, 0x28, 0xac, 0xe9, 0x48, 0x62, 0x24, 0x45 } };
|
static const GUID IID_ID3D12PipelineState = { 0x765a30f3, 0xf624, 0x4c6f, { 0xa8, 0x28, 0xac, 0xe9, 0x48, 0x62, 0x24, 0x45 } };
|
||||||
static const GUID IID_ID3D12Resource = { 0x696442be, 0xa72e, 0x4059, { 0xbc, 0x79, 0x5b, 0x5c, 0x98, 0x04, 0x0f, 0xad } };
|
static const GUID IID_ID3D12Resource = { 0x696442be, 0xa72e, 0x4059, { 0xbc, 0x79, 0x5b, 0x5c, 0x98, 0x04, 0x0f, 0xad } };
|
||||||
static const GUID IID_ID3D12RootSignature = { 0xc54a6b66, 0x72df, 0x4ee8, { 0x8b, 0xe5, 0xa9, 0x46, 0xa1, 0x42, 0x92, 0x14 } };
|
static const GUID IID_ID3D12RootSignature = { 0xc54a6b66, 0x72df, 0x4ee8, { 0x8b, 0xe5, 0xa9, 0x46, 0xa1, 0x42, 0x92, 0x14 } };
|
||||||
|
static const GUID IID_ID3D12QueryHeap = { 0x0d9658ae, 0xed45, 0x469e, { 0xa6, 0x1d, 0x97, 0x0e, 0xc5, 0x83, 0xca, 0xb4 } };
|
||||||
static const GUID IID_IDXGIFactory4 = { 0x1bc6ea02, 0xef36, 0x464f, { 0xbf, 0x0c, 0x21, 0xca, 0x39, 0xe5, 0x16, 0x8a } };
|
static const GUID IID_IDXGIFactory4 = { 0x1bc6ea02, 0xef36, 0x464f, { 0xbf, 0x0c, 0x21, 0xca, 0x39, 0xe5, 0x16, 0x8a } };
|
||||||
|
|
||||||
struct HeapProperty
|
struct HeapProperty
|
||||||
|
@ -885,6 +886,7 @@ namespace bgfx { namespace d3d12
|
||||||
// | BGFX_CAPS_SWAP_CHAIN
|
// | BGFX_CAPS_SWAP_CHAIN
|
||||||
| BGFX_CAPS_TEXTURE_BLIT
|
| BGFX_CAPS_TEXTURE_BLIT
|
||||||
| BGFX_CAPS_TEXTURE_READ_BACK
|
| BGFX_CAPS_TEXTURE_READ_BACK
|
||||||
|
| BGFX_CAPS_OCCLUSION_QUERY
|
||||||
);
|
);
|
||||||
g_caps.maxTextureSize = 16384;
|
g_caps.maxTextureSize = 16384;
|
||||||
g_caps.maxFBAttachments = uint8_t(bx::uint32_min(16, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) );
|
g_caps.maxFBAttachments = uint8_t(bx::uint32_min(16, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) );
|
||||||
|
@ -1036,6 +1038,7 @@ namespace bgfx { namespace d3d12
|
||||||
postReset();
|
postReset();
|
||||||
|
|
||||||
m_batch.create(4<<10);
|
m_batch.create(4<<10);
|
||||||
|
m_occlusionQuery.init();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -1069,6 +1072,8 @@ namespace bgfx { namespace d3d12
|
||||||
|
|
||||||
preReset();
|
preReset();
|
||||||
|
|
||||||
|
m_occlusionQuery.shutdown();
|
||||||
|
|
||||||
m_samplerAllocator.destroy();
|
m_samplerAllocator.destroy();
|
||||||
|
|
||||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_scratchBuffer); ++ii)
|
for (uint32_t ii = 0; ii < BX_COUNTOF(m_scratchBuffer); ++ii)
|
||||||
|
@ -2382,6 +2387,12 @@ data.NumQualityLevels = 0;
|
||||||
return sampler;
|
return sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isVisible(Frame* _render, OcclusionQueryHandle _handle, bool _visible)
|
||||||
|
{
|
||||||
|
m_occlusionQuery.resolve(_render);
|
||||||
|
return _visible == (0 != _render->m_occlusion[_handle.idx]);
|
||||||
|
}
|
||||||
|
|
||||||
void commit(UniformBuffer& _uniformBuffer)
|
void commit(UniformBuffer& _uniformBuffer)
|
||||||
{
|
{
|
||||||
_uniformBuffer.reset();
|
_uniformBuffer.reset();
|
||||||
|
@ -2552,7 +2563,7 @@ data.NumQualityLevels = 0;
|
||||||
rect.top = _rect.m_y;
|
rect.top = _rect.m_y;
|
||||||
rect.right = _rect.m_x + _rect.m_width;
|
rect.right = _rect.m_x + _rect.m_width;
|
||||||
rect.bottom = _rect.m_y + _rect.m_height;
|
rect.bottom = _rect.m_y + _rect.m_height;
|
||||||
clear(_clear, _palette, &rect);
|
clear(_clear, _palette, &rect, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2597,6 +2608,7 @@ data.NumQualityLevels = 0;
|
||||||
|
|
||||||
ID3D12Device* m_device;
|
ID3D12Device* m_device;
|
||||||
ID3D12InfoQueue* m_infoQueue;
|
ID3D12InfoQueue* m_infoQueue;
|
||||||
|
OcclusionQueryD3D12 m_occlusionQuery;
|
||||||
|
|
||||||
ID3D12DescriptorHeap* m_rtvDescriptorHeap;
|
ID3D12DescriptorHeap* m_rtvDescriptorHeap;
|
||||||
ID3D12DescriptorHeap* m_dsvDescriptorHeap;
|
ID3D12DescriptorHeap* m_dsvDescriptorHeap;
|
||||||
|
@ -4318,6 +4330,78 @@ data.NumQualityLevels = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OcclusionQueryD3D12::init()
|
||||||
|
{
|
||||||
|
D3D12_QUERY_HEAP_DESC queryHeapDesc;
|
||||||
|
queryHeapDesc.Count = BX_COUNTOF(m_query);
|
||||||
|
queryHeapDesc.NodeMask = 1;
|
||||||
|
queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
|
||||||
|
DX_CHECK(s_renderD3D12->m_device->CreateQueryHeap(&queryHeapDesc
|
||||||
|
, IID_ID3D12QueryHeap
|
||||||
|
, (void**)&m_queryHeap
|
||||||
|
) );
|
||||||
|
|
||||||
|
m_readback = createCommittedResource(s_renderD3D12->m_device
|
||||||
|
, HeapProperty::ReadBack
|
||||||
|
, BX_COUNTOF(m_query)*sizeof(uint64_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
D3D12_RANGE range = { 0, BX_COUNTOF(m_query) };
|
||||||
|
m_readback->Map(0, &range, (void**)&m_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OcclusionQueryD3D12::shutdown()
|
||||||
|
{
|
||||||
|
D3D12_RANGE range = { 0, 0 };
|
||||||
|
m_readback->Unmap(0, &range);
|
||||||
|
|
||||||
|
DX_RELEASE(m_queryHeap, 0);
|
||||||
|
DX_RELEASE(m_readback, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OcclusionQueryD3D12::begin(ID3D12GraphicsCommandList* _commandList, Frame* _render, OcclusionQueryHandle _handle)
|
||||||
|
{
|
||||||
|
while (0 == m_control.reserve(1) )
|
||||||
|
{
|
||||||
|
resolve(_render);
|
||||||
|
}
|
||||||
|
|
||||||
|
Query& query = m_query[m_control.m_current];
|
||||||
|
query.m_handle = _handle;
|
||||||
|
_commandList->BeginQuery(m_queryHeap
|
||||||
|
, D3D12_QUERY_TYPE_BINARY_OCCLUSION
|
||||||
|
, _handle.idx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OcclusionQueryD3D12::end(ID3D12GraphicsCommandList* _commandList)
|
||||||
|
{
|
||||||
|
Query& query = m_query[m_control.m_current];
|
||||||
|
_commandList->EndQuery(m_queryHeap
|
||||||
|
, D3D12_QUERY_TYPE_BINARY_OCCLUSION
|
||||||
|
, query.m_handle.idx
|
||||||
|
);
|
||||||
|
_commandList->ResolveQueryData(m_queryHeap
|
||||||
|
, D3D12_QUERY_TYPE_BINARY_OCCLUSION
|
||||||
|
, query.m_handle.idx
|
||||||
|
, 1
|
||||||
|
, m_readback
|
||||||
|
, query.m_handle.idx * sizeof(uint64_t)
|
||||||
|
);
|
||||||
|
m_control.commit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OcclusionQueryD3D12::resolve(Frame* _render)
|
||||||
|
{
|
||||||
|
while (0 != m_control.available() )
|
||||||
|
{
|
||||||
|
Query& query = m_query[m_control.m_read];
|
||||||
|
|
||||||
|
_render->m_occlusion[query.m_handle.idx] = 0 < m_result[query.m_handle.idx];
|
||||||
|
m_control.consume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Bind
|
struct Bind
|
||||||
{
|
{
|
||||||
D3D12_GPU_DESCRIPTOR_HANDLE m_srvHandle;
|
D3D12_GPU_DESCRIPTOR_HANDLE m_srvHandle;
|
||||||
|
@ -4413,6 +4497,8 @@ data.NumQualityLevels = 0;
|
||||||
, D3D12_RESOURCE_STATE_RENDER_TARGET
|
, D3D12_RESOURCE_STATE_RENDER_TARGET
|
||||||
);
|
);
|
||||||
|
|
||||||
|
m_occlusionQuery.resolve(_render);
|
||||||
|
|
||||||
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
|
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
|
||||||
{
|
{
|
||||||
m_batch.begin();
|
m_batch.begin();
|
||||||
|
@ -4718,6 +4804,14 @@ data.NumQualityLevels = 0;
|
||||||
|
|
||||||
const RenderDraw& draw = renderItem.draw;
|
const RenderDraw& draw = renderItem.draw;
|
||||||
|
|
||||||
|
const bool hasOcclusionQuery = 0 != (draw.m_stateFlags & BGFX_STATE_INTERNAL_OCCLUSION_QUERY);
|
||||||
|
if (isValid(draw.m_occlusionQuery)
|
||||||
|
&& !hasOcclusionQuery
|
||||||
|
&& !isVisible(_render, draw.m_occlusionQuery, 0 != (draw.m_submitFlags&BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const uint64_t newFlags = draw.m_stateFlags;
|
const uint64_t newFlags = draw.m_stateFlags;
|
||||||
uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags;
|
uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags;
|
||||||
currentState.m_stateFlags = newFlags;
|
currentState.m_stateFlags = newFlags;
|
||||||
|
@ -4801,7 +4895,8 @@ data.NumQualityLevels = 0;
|
||||||
|| (0 != (BGFX_STATE_PT_MASK & changedFlags)
|
|| (0 != (BGFX_STATE_PT_MASK & changedFlags)
|
||||||
|| prim.m_toplogy != s_primInfo[primIndex].m_toplogy)
|
|| prim.m_toplogy != s_primInfo[primIndex].m_toplogy)
|
||||||
|| currentState.m_scissor != scissor
|
|| currentState.m_scissor != scissor
|
||||||
|| pso != currentPso)
|
|| pso != currentPso
|
||||||
|
|| hasOcclusionQuery)
|
||||||
{
|
{
|
||||||
m_batch.flush(m_commandList);
|
m_batch.flush(m_commandList);
|
||||||
}
|
}
|
||||||
|
@ -4977,6 +5072,13 @@ data.NumQualityLevels = 0;
|
||||||
statsNumPrimsRendered[primIndex] += numPrimsRendered;
|
statsNumPrimsRendered[primIndex] += numPrimsRendered;
|
||||||
statsNumInstances[primIndex] += draw.m_numInstances;
|
statsNumInstances[primIndex] += draw.m_numInstances;
|
||||||
statsNumIndices += numIndices;
|
statsNumIndices += numIndices;
|
||||||
|
|
||||||
|
if (hasOcclusionQuery)
|
||||||
|
{
|
||||||
|
m_occlusionQuery.begin(m_commandList, _render, draw.m_occlusionQuery);
|
||||||
|
m_batch.flush(m_commandList);
|
||||||
|
m_occlusionQuery.end(m_commandList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -432,6 +432,31 @@ namespace bgfx { namespace d3d12
|
||||||
uint32_t m_flushPerBatch;
|
uint32_t m_flushPerBatch;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OcclusionQueryD3D12
|
||||||
|
{
|
||||||
|
OcclusionQueryD3D12()
|
||||||
|
: m_control(BX_COUNTOF(m_query) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void shutdown();
|
||||||
|
void begin(ID3D12GraphicsCommandList* _commandList, Frame* _render, OcclusionQueryHandle _handle);
|
||||||
|
void end(ID3D12GraphicsCommandList* _commandList);
|
||||||
|
void resolve(Frame* _render);
|
||||||
|
|
||||||
|
struct Query
|
||||||
|
{
|
||||||
|
OcclusionQueryHandle m_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
ID3D12Resource* m_readback;
|
||||||
|
ID3D12QueryHeap* m_queryHeap;
|
||||||
|
Query m_query[BGFX_CONFIG_MAX_OCCUSION_QUERIES];
|
||||||
|
uint64_t* m_result;
|
||||||
|
bx::RingBufferControl m_control;
|
||||||
|
};
|
||||||
|
|
||||||
} /* namespace d3d12 */ } // namespace bgfx
|
} /* namespace d3d12 */ } // namespace bgfx
|
||||||
|
|
||||||
#endif // BGFX_RENDERER_D3D12_H_HEADER_GUARD
|
#endif // BGFX_RENDERER_D3D12_H_HEADER_GUARD
|
||||||
|
|
Loading…
Reference in a new issue