Sampler state caching.
This commit is contained in:
parent
6607606b15
commit
529a1478d8
|
@ -845,9 +845,6 @@ int D3D11GraphicsDriver::BindShaders() {
|
|||
|
||||
// Setup input layout (as encoded in vertex shader).
|
||||
context_->IASetInputLayout(vs->input_layout());
|
||||
|
||||
//context_->VSSetSamplers
|
||||
//context_->VSSetShaderResources
|
||||
} else {
|
||||
context_->VSSetShader(NULL, NULL, 0);
|
||||
context_->IASetInputLayout(NULL);
|
||||
|
@ -877,27 +874,6 @@ int D3D11GraphicsDriver::BindShaders() {
|
|||
};
|
||||
context_->PSSetConstantBuffers(
|
||||
0, XECOUNT(vs_constant_buffers), vs_constant_buffers);
|
||||
|
||||
// TODO(benvanik): set samplers for all inputs.
|
||||
D3D11_SAMPLER_DESC sampler_desc;
|
||||
xe_zero_struct(&sampler_desc, sizeof(sampler_desc));
|
||||
//sampler_desc.Filter = ?
|
||||
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampler_desc.MipLODBias = 0;
|
||||
sampler_desc.MaxAnisotropy = 1;
|
||||
sampler_desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
//sampler_desc.BorderColor = ...;
|
||||
sampler_desc.MinLOD = 0;
|
||||
sampler_desc.MaxLOD = 0;
|
||||
ID3D11SamplerState* sampler_state = NULL;
|
||||
device_->CreateSamplerState(&sampler_desc, &sampler_state);
|
||||
ID3D11SamplerState* sampler_states[] = { sampler_state };
|
||||
context_->PSSetSamplers(0, XECOUNT(sampler_states), sampler_states);
|
||||
sampler_state->Release();
|
||||
|
||||
//context_->PSSetShaderResources
|
||||
} else {
|
||||
context_->PSSetShader(NULL, NULL, 0);
|
||||
return 1;
|
||||
|
@ -1109,7 +1085,6 @@ int D3D11GraphicsDriver::PrepareTextureSampler(
|
|||
} else {
|
||||
context_->PSSetSamplers(desc.input_index, 1, &sampler_state);
|
||||
}
|
||||
XESAFERELEASE(sampler_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,12 @@ D3D11TextureCache::D3D11TextureCache(
|
|||
}
|
||||
|
||||
D3D11TextureCache::~D3D11TextureCache() {
|
||||
for (auto it = samplers_.begin(); it != samplers_.end(); ++it) {
|
||||
auto& cached_state = it->second;
|
||||
XESAFERELEASE(cached_state.state);
|
||||
}
|
||||
samplers_.clear();
|
||||
|
||||
XESAFERELEASE(device_);
|
||||
XESAFERELEASE(context_);
|
||||
}
|
||||
|
@ -103,11 +109,30 @@ ID3D11SamplerState* D3D11TextureCache::GetSamplerState(
|
|||
sampler_desc.BorderColor[3];
|
||||
sampler_desc.MinLOD;
|
||||
sampler_desc.MaxLOD;
|
||||
|
||||
// TODO(benvanik): do this earlier without having to setup the whole struct?
|
||||
size_t hash = hash_combine(
|
||||
sampler_desc.Filter,
|
||||
sampler_desc.AddressU,
|
||||
sampler_desc.AddressV,
|
||||
sampler_desc.AddressW);
|
||||
auto range = samplers_.equal_range(hash);
|
||||
for (auto it = range.first; it != range.second; ++it) {
|
||||
const auto& cached_state = it->second;
|
||||
// TODO(benvanik): faster compare?
|
||||
if (memcmp(&sampler_desc, &cached_state.desc, sizeof(sampler_desc)) == 0) {
|
||||
return cached_state.state;
|
||||
}
|
||||
}
|
||||
|
||||
ID3D11SamplerState* sampler_state = NULL;
|
||||
HRESULT hr = device_->CreateSamplerState(&sampler_desc, &sampler_state);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: unable to create sampler state");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
samplers_.insert({ hash, { sampler_desc, sampler_state } });
|
||||
|
||||
return sampler_state;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,12 @@ protected:
|
|||
private:
|
||||
ID3D11DeviceContext* context_;
|
||||
ID3D11Device* device_;
|
||||
|
||||
struct CachedSamplerState {
|
||||
D3D11_SAMPLER_DESC desc;
|
||||
ID3D11SamplerState* state;
|
||||
};
|
||||
std::unordered_multimap<size_t, CachedSamplerState> samplers_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -134,6 +134,16 @@ typedef XECACHEALIGN volatile void xe_aligned_void_t;
|
|||
#endif // GNUC
|
||||
#endif // !MIN
|
||||
|
||||
XEFORCEINLINE size_t hash_combine(size_t seed) {
|
||||
return seed;
|
||||
}
|
||||
template <typename T, typename... Ts>
|
||||
size_t hash_combine(size_t seed, const T& v, const Ts&... vs) {
|
||||
std::hash<T> hasher;
|
||||
seed ^= hasher(v) + 0x9E3779B9 + (seed << 6) + (seed >> 2);
|
||||
return hash_combine(seed, vs...);
|
||||
}
|
||||
|
||||
#if XE_PLATFORM_WIN32
|
||||
#define XESAFERELEASE(p) if (p) { p->Release(); }
|
||||
#endif // WIN32
|
||||
|
|
Loading…
Reference in New Issue