mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-28 18:45:54 -05:00
D3D: Added state cache LRU.
This commit is contained in:
parent
976c152111
commit
06a865cb7b
4 changed files with 108 additions and 31 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
;
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue