D3D: Added state cache LRU.

This commit is contained in:
Branimir Karadžić 2015-08-13 22:56:28 -07:00
parent 976c152111
commit 06a865cb7b
4 changed files with 108 additions and 31 deletions

View file

@ -192,6 +192,69 @@ namespace bgfx
HashMap m_hashMap;
};
template <typename Ty, uint16_t MaxHandleT>
class StateCacheLru
{
public:
void add(uint64_t _hash, Ty _value)
{
uint16_t handle = m_alloc.alloc();
if (UINT16_MAX == handle)
{
uint16_t back = m_alloc.getBack();
m_alloc.free(back);
HashMap::iterator it = m_hashMap.find(m_data[back].m_hash);
if (it != m_hashMap.end() )
{
m_hashMap.erase(it);
}
handle = m_alloc.alloc();
}
BX_CHECK(UINT16_MAX != handle, "Failed to find handle.");
Data& data = m_data[handle];
data.m_hash = _hash;
data.m_value = _value;
m_hashMap.insert(stl::make_pair(_hash, handle) );
}
Ty* find(uint64_t _hash)
{
HashMap::iterator it = m_hashMap.find(_hash);
if (it != m_hashMap.end() )
{
return &m_data[it->second].m_value;
}
return NULL;
}
void invalidate()
{
m_hashMap.clear();
m_alloc.reset();
}
uint32_t getCount() const
{
return uint32_t(m_hashMap.size() );
}
private:
typedef stl::unordered_map<uint64_t, uint16_t> HashMap;
HashMap m_hashMap;
bx::HandleAllocLruT<MaxHandleT> m_alloc;
struct Data
{
uint64_t m_hash;
Ty m_value;
};
Data m_data[MaxHandleT];
};
} // namespace bgfx
#endif // BGFX_RENDERER_D3D_H_HEADER_GUARD

View file

@ -680,6 +680,7 @@ namespace bgfx { namespace d3d11
uint32_t flags = 0
| D3D11_CREATE_DEVICE_SINGLETHREADED
| D3D11_CREATE_DEVICE_BGRA_SUPPORT
// | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
| (BX_ENABLED(BGFX_CONFIG_DEBUG) ? D3D11_CREATE_DEVICE_DEBUG : 0)
;

View file

@ -702,7 +702,7 @@ namespace bgfx { namespace d3d12
filter.DenyList.pCategoryList = catlist;
m_infoQueue->PushStorageFilter(&filter);
DX_RELEASE(m_infoQueue, 19);
DX_RELEASE_WARNONLY(m_infoQueue, 19);
}
}
@ -3690,6 +3690,7 @@ data.NumQualityLevels = 0;
scratchBuffer.reset(gpuHandle);
D3D12_GPU_VIRTUAL_ADDRESS gpuAddress = {};
StateCacheLru<D3D12_GPU_DESCRIPTOR_HANDLE, 64> bindLru;
setResourceBarrier(m_commandList
, m_backBufferColor[m_backBufferColorIdx]
@ -4068,6 +4069,9 @@ data.NumQualityLevels = 0;
; currentBindHash != bindHash
; currentBindHash = bindHash
)
{
D3D12_GPU_DESCRIPTOR_HANDLE* srv = bindLru.find(bindHash);
if (NULL == srv)
{
D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
uint32_t samplerFlags[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
@ -4104,6 +4108,13 @@ data.NumQualityLevels = 0;
}
m_commandList->SetGraphicsRootDescriptorTable(Rdt::SRV, srvHandle[0]);
bindLru.add(bindHash, srvHandle[0]);
}
}
else
{
m_commandList->SetGraphicsRootDescriptorTable(Rdt::SRV, *srv);
}
}
@ -4335,10 +4346,11 @@ data.NumQualityLevels = 0;
pos++;
tvm.printf(10, pos++, 0x8e, " State cache: ");
tvm.printf(10, pos++, 0x8e, " PSO | Sampler | Queued ");
tvm.printf(10, pos++, 0x8e, " %6d | %6d | %6d"
tvm.printf(10, pos++, 0x8e, " PSO | Sampler | Bind | Queued ");
tvm.printf(10, pos++, 0x8e, " %6d | %6d | %6d | %6d"
, m_pipelineStateCache.getCount()
, m_samplerStateCache.getCount()
, bindLru.getCount()
, m_cmd.m_control.available()
);
pos++;

View file

@ -297,6 +297,7 @@ namespace bgfx { namespace d3d12
CommandQueue()
: m_control(BX_COUNTOF(m_commandList) )
{
BX_STATIC_ASSERT(BX_COUNTOF(m_commandList) == BX_COUNTOF(m_release) );
}
void init(ID3D12Device* _device)
@ -454,9 +455,9 @@ namespace bgfx { namespace d3d12
uint64_t m_currentFence;
uint64_t m_completedFence;
ID3D12Fence* m_fence;
CommandList m_commandList[4];
CommandList m_commandList[32];
typedef stl::vector<ID3D12Resource*> ResourceArray;
ResourceArray m_release[4];
ResourceArray m_release[32];
bx::RingBufferControl m_control;
};