Sampler state caching.

This commit is contained in:
Ben Vanik 2014-05-31 16:34:05 -07:00
parent 6607606b15
commit 529a1478d8
4 changed files with 41 additions and 25 deletions

View File

@ -845,9 +845,6 @@ int D3D11GraphicsDriver::BindShaders() {
// Setup input layout (as encoded in vertex shader). // Setup input layout (as encoded in vertex shader).
context_->IASetInputLayout(vs->input_layout()); context_->IASetInputLayout(vs->input_layout());
//context_->VSSetSamplers
//context_->VSSetShaderResources
} else { } else {
context_->VSSetShader(NULL, NULL, 0); context_->VSSetShader(NULL, NULL, 0);
context_->IASetInputLayout(NULL); context_->IASetInputLayout(NULL);
@ -877,27 +874,6 @@ int D3D11GraphicsDriver::BindShaders() {
}; };
context_->PSSetConstantBuffers( context_->PSSetConstantBuffers(
0, XECOUNT(vs_constant_buffers), vs_constant_buffers); 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 { } else {
context_->PSSetShader(NULL, NULL, 0); context_->PSSetShader(NULL, NULL, 0);
return 1; return 1;
@ -1109,7 +1085,6 @@ int D3D11GraphicsDriver::PrepareTextureSampler(
} else { } else {
context_->PSSetSamplers(desc.input_index, 1, &sampler_state); context_->PSSetSamplers(desc.input_index, 1, &sampler_state);
} }
XESAFERELEASE(sampler_state);
return 0; return 0;
} }

View File

@ -27,6 +27,12 @@ D3D11TextureCache::D3D11TextureCache(
} }
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(device_);
XESAFERELEASE(context_); XESAFERELEASE(context_);
} }
@ -103,11 +109,30 @@ ID3D11SamplerState* D3D11TextureCache::GetSamplerState(
sampler_desc.BorderColor[3]; sampler_desc.BorderColor[3];
sampler_desc.MinLOD; sampler_desc.MinLOD;
sampler_desc.MaxLOD; 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; ID3D11SamplerState* sampler_state = NULL;
HRESULT hr = device_->CreateSamplerState(&sampler_desc, &sampler_state); HRESULT hr = device_->CreateSamplerState(&sampler_desc, &sampler_state);
if (FAILED(hr)) { if (FAILED(hr)) {
XELOGE("D3D11: unable to create sampler state"); XELOGE("D3D11: unable to create sampler state");
return nullptr; return nullptr;
} }
samplers_.insert({ hash, { sampler_desc, sampler_state } });
return sampler_state; return sampler_state;
} }

View File

@ -44,6 +44,12 @@ protected:
private: private:
ID3D11DeviceContext* context_; ID3D11DeviceContext* context_;
ID3D11Device* device_; ID3D11Device* device_;
struct CachedSamplerState {
D3D11_SAMPLER_DESC desc;
ID3D11SamplerState* state;
};
std::unordered_multimap<size_t, CachedSamplerState> samplers_;
}; };

View File

@ -134,6 +134,16 @@ typedef XECACHEALIGN volatile void xe_aligned_void_t;
#endif // GNUC #endif // GNUC
#endif // !MIN #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 #if XE_PLATFORM_WIN32
#define XESAFERELEASE(p) if (p) { p->Release(); } #define XESAFERELEASE(p) if (p) { p->Release(); }
#endif // WIN32 #endif // WIN32