Use raw pointers for the routine const cache.
As these are touched by pixel shaders, this is extraordinarily hot code, and the cost of ref-counting by shared_ptr can really impact performance.
As the const cache is updated at well known sync points, the queryConstCache method is safe to return a raw pointer to the routine.
Bug: b/137524292
Bug: b/137649247
Change-Id: I2ae1f159467eb27b918344714cef1963f3b24a45
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/34453
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
diff --git a/src/Device/LRUCache.hpp b/src/Device/LRUCache.hpp
index 9f6c120..083861e 100644
--- a/src/Device/LRUCache.hpp
+++ b/src/Device/LRUCache.hpp
@@ -63,7 +63,7 @@
}
void updateConstCache();
- Data queryConstCache(const Key &key) const;
+ const Data& queryConstCache(const Key &key) const;
private:
void clearConstCache();
@@ -215,10 +215,11 @@
}
template<class Key, class Data>
- Data LRUConstCache<Key, Data>::queryConstCache(const Key &key) const
+ const Data& LRUConstCache<Key, Data>::queryConstCache(const Key &key) const
{
auto it = constCache.find(key);
- return (it != constCache.end()) ? it->second : nullptr;
+ static Data null = {};
+ return (it != constCache.end()) ? it->second : null;
}
}
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index 5e56977..6a232fd 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -40,8 +40,7 @@
ASSERT(imageDescriptor->device);
- auto routine = imageDescriptor->device->findInConstCache(key);
- if(routine)
+ if(auto routine = imageDescriptor->device->findInConstCache(key))
{
return (ImageSampler*)(routine->getEntry());
}
@@ -49,7 +48,7 @@
std::unique_lock<std::mutex> lock(imageDescriptor->device->getSamplingRoutineCacheMutex());
vk::Device::SamplingRoutineCache* cache = imageDescriptor->device->getSamplingRoutineCache();
- routine = cache->query(key);
+ auto routine = cache->query(key);
if(routine)
{
return (ImageSampler*)(routine->getEntry());
diff --git a/src/Vulkan/VkDevice.cpp b/src/Vulkan/VkDevice.cpp
index 230d2d0..bceb001 100644
--- a/src/Vulkan/VkDevice.cpp
+++ b/src/Vulkan/VkDevice.cpp
@@ -47,9 +47,9 @@
cache.add(hash(key), routine);
}
-std::shared_ptr<rr::Routine> Device::SamplingRoutineCache::queryConst(const vk::Device::SamplingRoutineCache::Key& key) const
+rr::Routine* Device::SamplingRoutineCache::queryConst(const vk::Device::SamplingRoutineCache::Key& key) const
{
- return cache.queryConstCache(hash(key));
+ return cache.queryConstCache(hash(key)).get();
}
void Device::SamplingRoutineCache::updateConstCache()
@@ -251,7 +251,7 @@
return samplingRoutineCache.get();
}
-std::shared_ptr<rr::Routine> Device::findInConstCache(const SamplingRoutineCache::Key& key) const
+rr::Routine* Device::findInConstCache(const SamplingRoutineCache::Key& key) const
{
return samplingRoutineCache->queryConst(key);
}
diff --git a/src/Vulkan/VkDevice.hpp b/src/Vulkan/VkDevice.hpp
index 721dda2..742d662 100644
--- a/src/Vulkan/VkDevice.hpp
+++ b/src/Vulkan/VkDevice.hpp
@@ -70,7 +70,7 @@
std::shared_ptr<rr::Routine> query(const Key& key) const;
void add(const Key& key, const std::shared_ptr<rr::Routine>& routine);
- std::shared_ptr<rr::Routine> queryConst(const Key& key) const;
+ rr::Routine* queryConst(const Key& key) const;
void updateConstCache();
static std::size_t hash(const Key &key);
@@ -81,7 +81,7 @@
SamplingRoutineCache* getSamplingRoutineCache() const;
std::mutex& getSamplingRoutineCacheMutex();
- std::shared_ptr<rr::Routine> findInConstCache(const SamplingRoutineCache::Key& key) const;
+ rr::Routine* findInConstCache(const SamplingRoutineCache::Key& key) const;
void updateSamplingRoutineConstCache();
private: