From 06a865cb7b41bae6dedf2d223ad0ed50fde039a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 13 Aug 2015 22:56:28 -0700 Subject: [PATCH] D3D: Added state cache LRU. --- src/renderer_d3d.h | 63 +++++++++++++++++++++++++++++++++++++ src/renderer_d3d11.cpp | 1 + src/renderer_d3d12.cpp | 70 +++++++++++++++++++++++++----------------- src/renderer_d3d12.h | 5 +-- 4 files changed, 108 insertions(+), 31 deletions(-) diff --git a/src/renderer_d3d.h b/src/renderer_d3d.h index 9441351f..d281d8c9 100644 --- a/src/renderer_d3d.h +++ b/src/renderer_d3d.h @@ -192,6 +192,69 @@ namespace bgfx HashMap m_hashMap; }; + template + 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 HashMap; + HashMap m_hashMap; + bx::HandleAllocLruT m_alloc; + struct Data + { + uint64_t m_hash; + Ty m_value; + }; + + Data m_data[MaxHandleT]; + }; + } // namespace bgfx #endif // BGFX_RENDERER_D3D_H_HEADER_GUARD diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index e33fcb31..0d3b7ca8 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -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) ; diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 65d0386a..2dd8a168 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -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 bindLru; setResourceBarrier(m_commandList , m_backBufferColor[m_backBufferColorIdx] @@ -4069,41 +4070,51 @@ data.NumQualityLevels = 0; ; currentBindHash = bindHash ) { - D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; - uint32_t samplerFlags[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; + D3D12_GPU_DESCRIPTOR_HANDLE* srv = bindLru.find(bindHash); + if (NULL == srv) { - srvHandle[0].ptr = 0; - for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) + D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; + uint32_t samplerFlags[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; { - const Binding& sampler = draw.m_bind[stage]; - if (invalidHandle != sampler.m_idx) + srvHandle[0].ptr = 0; + for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { - TextureD3D12& texture = m_textures[sampler.m_idx]; - scratchBuffer.alloc(srvHandle[stage], texture); - samplerFlags[stage] = (0 == (BGFX_SAMPLER_DEFAULT_FLAGS & sampler.m_un.m_draw.m_flags) - ? sampler.m_un.m_draw.m_flags - : texture.m_flags - ) & BGFX_TEXTURE_SAMPLER_BITS_MASK - ; + const Binding& sampler = draw.m_bind[stage]; + if (invalidHandle != sampler.m_idx) + { + TextureD3D12& texture = m_textures[sampler.m_idx]; + scratchBuffer.alloc(srvHandle[stage], texture); + samplerFlags[stage] = (0 == (BGFX_SAMPLER_DEFAULT_FLAGS & sampler.m_un.m_draw.m_flags) + ? sampler.m_un.m_draw.m_flags + : texture.m_flags + ) & BGFX_TEXTURE_SAMPLER_BITS_MASK + ; + } + else + { + memcpy(&srvHandle[stage], &srvHandle[0], sizeof(D3D12_GPU_DESCRIPTOR_HANDLE) ); + samplerFlags[stage] = 0; + } } - else + } + + if (srvHandle[0].ptr != 0) + { + uint16_t samplerStateIdx = getSamplerState(samplerFlags); + if (samplerStateIdx != currentSamplerStateIdx) { - memcpy(&srvHandle[stage], &srvHandle[0], sizeof(D3D12_GPU_DESCRIPTOR_HANDLE) ); - samplerFlags[stage] = 0; + currentSamplerStateIdx = samplerStateIdx; + m_commandList->SetGraphicsRootDescriptorTable(Rdt::Sampler, m_samplerAllocator.get(samplerStateIdx) ); } + + m_commandList->SetGraphicsRootDescriptorTable(Rdt::SRV, srvHandle[0]); + + bindLru.add(bindHash, srvHandle[0]); } } - - if (srvHandle[0].ptr != 0) + else { - uint16_t samplerStateIdx = getSamplerState(samplerFlags); - if (samplerStateIdx != currentSamplerStateIdx) - { - currentSamplerStateIdx = samplerStateIdx; - m_commandList->SetGraphicsRootDescriptorTable(Rdt::Sampler, m_samplerAllocator.get(samplerStateIdx) ); - } - - m_commandList->SetGraphicsRootDescriptorTable(Rdt::SRV, srvHandle[0]); + 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++; diff --git a/src/renderer_d3d12.h b/src/renderer_d3d12.h index 954588ab..2162cfc3 100644 --- a/src/renderer_d3d12.h +++ b/src/renderer_d3d12.h @@ -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 ResourceArray; - ResourceArray m_release[4]; + ResourceArray m_release[32]; bx::RingBufferControl m_control; };