Commit 8f77a7dd authored by Joshua Ashton's avatar Joshua Ashton 🐸

[d3d9] Use xxhash for state lookup.

parent 281f93e9
Pipeline #61 passed with stage
in 1 minute and 38 seconds
......@@ -369,7 +369,8 @@ namespace dxup {
desc.StencilReadMask = (UINT8)(m_state->renderState[D3DRS_STENCILMASK] & 0x000000FF); // I think we can do this.
desc.StencilWriteMask = (UINT8)(m_state->renderState[D3DRS_STENCILWRITEMASK] & 0x000000FF);
ID3D11DepthStencilState* state = m_caches.depthStencil.lookupObject(desc);
size_t hash = m_caches.depthStencil.hash(desc);
ID3D11DepthStencilState* state = m_caches.depthStencil.lookupObject(hash);
if (state == nullptr) {
Com<ID3D11DepthStencilState> comState;
......@@ -380,7 +381,7 @@ namespace dxup {
return;
}
m_caches.depthStencil.pushState(desc, comState.ptr());
m_caches.depthStencil.pushState(hash, desc, comState.ptr());
state = comState.ptr();
}
......@@ -402,7 +403,8 @@ namespace dxup {
desc.ScissorEnable = m_state->renderState[D3DRS_SCISSORTESTENABLE] == TRUE ? TRUE : FALSE;
desc.SlopeScaledDepthBias = reinterpret::dwordToFloat(m_state->renderState[D3DRS_SLOPESCALEDEPTHBIAS]);
ID3D11RasterizerState1* state = m_caches.rasterizer.lookupObject(desc);
size_t hash = m_caches.rasterizer.hash(desc);
ID3D11RasterizerState1* state = m_caches.rasterizer.lookupObject(hash);
if (state == nullptr) {
Com<ID3D11RasterizerState1> comState;
......@@ -413,7 +415,7 @@ namespace dxup {
return;
}
m_caches.rasterizer.pushState(desc, comState.ptr());
m_caches.rasterizer.pushState(hash, desc, comState.ptr());
state = comState.ptr();
}
......@@ -456,7 +458,8 @@ namespace dxup {
desc.RenderTarget[i].SrcBlendAlpha = separateAlpha ? convert::blend(m_state->renderState[D3DRS_SRCBLENDALPHA]) : D3D11_BLEND_ONE;
}
ID3D11BlendState1* state = m_caches.blendState.lookupObject(desc);
size_t hash = m_caches.blendState.hash(desc);
ID3D11BlendState1* state = m_caches.blendState.lookupObject(hash);
if (state == nullptr) {
Com<ID3D11BlendState1> comState;
......@@ -467,7 +470,7 @@ namespace dxup {
return;
}
m_caches.blendState.pushState(desc, comState.ptr());
m_caches.blendState.pushState(hash, desc, comState.ptr());
state = comState.ptr();
}
......@@ -490,7 +493,8 @@ namespace dxup {
desc.MaxLOD = (FLOAT)samplerState[D3DSAMP_MAXMIPLEVEL];
desc.MinLOD = -FLT_MAX;
ID3D11SamplerState* state = m_caches.sampler.lookupObject(desc);
size_t hash = m_caches.sampler.hash(desc);
ID3D11SamplerState* state = m_caches.sampler.lookupObject(hash);
if (state == nullptr) {
Com<ID3D11SamplerState> comState;
......@@ -501,7 +505,7 @@ namespace dxup {
return;
}
m_caches.sampler.pushState(desc, comState.ptr());
m_caches.sampler.pushState(hash, desc, comState.ptr());
state = comState.ptr();
}
......
#include "d3d9_state_cache.h"
#define XXH_INLINE_ALL
#include "../extern/xxhash/xxhash.h"
namespace dxup {
// These hash functions only include states that we change to avoid collisions!
// Remember to update me if we do change more states!
template <typename T>
inline size_t hashDesc(const T& desc) {
#ifdef _WIN32
return XXH32(&desc, sizeof(T), 0);
#else
return XXH64(&desc, sizeof(T), 0);
#endif
}
size_t D3D11StateDescHash::operator () (const D3D11_SAMPLER_DESC& desc) const {
HashState hash;
std::hash<float> fhash;
hash.add(desc.AddressU);
hash.add(desc.AddressV);
hash.add(desc.AddressW);
for (uint32_t i = 0; i < 4; i++)
hash.add(fhash(desc.BorderColor[i]));
hash.add(desc.Filter);
hash.add(desc.MaxAnisotropy);
hash.add(fhash(desc.MipLODBias));
hash.add(fhash(desc.MaxLOD));
return hash;
return hashDesc(desc);
}
size_t D3D11StateDescHash::operator () (const D3D11_RENDER_TARGET_BLEND_DESC1& desc) const {
HashState hash;
hash.add(desc.BlendEnable);
hash.add(desc.SrcBlend);
hash.add(desc.DestBlend);
hash.add(desc.BlendOp);
hash.add(desc.SrcBlendAlpha);
hash.add(desc.DestBlendAlpha);
hash.add(desc.BlendOpAlpha);
hash.add(desc.RenderTargetWriteMask);
return hash;
return hashDesc(desc);
}
size_t D3D11StateDescHash::operator () (const D3D11_BLEND_DESC1& desc) const {
HashState hash;
// For now we only use one.
hash.add(this->operator()(desc.RenderTarget[0]));
return hash;
return hashDesc(desc.RenderTarget[0]);
}
size_t D3D11StateDescHash::operator () (const D3D11_RASTERIZER_DESC1& desc) const {
std::hash<float> fhash;
HashState hash;
hash.add(desc.FillMode);
hash.add(desc.CullMode);
hash.add(desc.DepthBias);
hash.add(fhash(desc.SlopeScaledDepthBias));
hash.add(fhash(desc.DepthBiasClamp));
hash.add(desc.ScissorEnable);
hash.add(desc.MultisampleEnable); // Sample stuff is included even though we don't use it because we probably will soon.
hash.add(desc.AntialiasedLineEnable);
hash.add(desc.ForcedSampleCount);
return hash;
return hashDesc(desc);
}
size_t D3D11StateDescHash::operator () (const D3D11_DEPTH_STENCILOP_DESC& desc) const {
HashState hash;
hash.add(desc.StencilFunc);
hash.add(desc.StencilDepthFailOp);
hash.add(desc.StencilPassOp);
hash.add(desc.StencilFailOp);
return hash;
return hashDesc(desc);
}
size_t D3D11StateDescHash::operator () (const D3D11_DEPTH_STENCIL_DESC& desc) const {
HashState hash;
hash.add(desc.DepthEnable);
hash.add(desc.DepthWriteMask);
hash.add(desc.DepthFunc);
hash.add(desc.StencilEnable);
hash.add(desc.StencilReadMask);
hash.add(desc.StencilWriteMask);
hash.add(this->operator () (desc.FrontFace));
hash.add(this->operator () (desc.BackFace));
return hash;
return hashDesc(desc);
}
// eq
......
......@@ -2,7 +2,6 @@
#include <vector>
#include <string>
#include "d3d9_base.h"
#include <unordered_map>
#include "../util/hash.h"
......@@ -31,24 +30,30 @@ namespace dxup {
public:
using StateMap = std::unordered_map<Desc, Com<Object>, D3D11StateDescHash, D3D11StateDescEqual>;
Object* lookupObject(const Desc& desc) {
typename StateMap::const_iterator iter = m_map.find(desc);
if (iter == m_map.end())
return nullptr;
using StatePair = std::pair<size_t, Com<Object>>;
size_t hash(const Desc& desc) {
static D3D11StateDescHash hasher;
return hasher.operator()(desc);
}
return iter->second.ptr();
Object* lookupObject(size_t hash) {
for (const auto& obj : m_objects) {
if (obj.first == hash)
return obj.second.ptr();
}
return nullptr;
}
void pushState(const Desc& desc, Object* object) {
m_map.emplace(desc, object);
void pushState(size_t hash, const Desc& desc, Object* object) {
StatePair pair = StatePair{ hash, object };
m_objects.push_back(pair);
}
private:
StateMap m_map;
std::vector<StatePair> m_objects;
};
}
\ No newline at end of file
xxHash Library
Copyright (c) 2012-2014, Yann Collet
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment