Don't expose the sampling routine cache's mutex
The getOrCreate() method takes care of the mutex locking and unlocking,
and takes the function for creating the routine as a callback argument.
Bug: b/131246679
Change-Id: I0873f6be94c92a11181ce575d1b44ed040177d43
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/42869
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index adc465b..dd84e70 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -45,58 +45,54 @@
return (ImageSampler *)(routine->getEntry());
}
- std::unique_lock<std::mutex> lock(imageDescriptor->device->getSamplingRoutineCacheMutex());
vk::Device::SamplingRoutineCache *cache = imageDescriptor->device->getSamplingRoutineCache();
- auto routine = cache->query(key);
- if(routine)
- {
- return (ImageSampler *)(routine->getEntry());
- }
+ auto createSamplingRoutine = [&](const vk::Device::SamplingRoutineCache::Key &key) {
+ auto type = imageDescriptor->type;
- auto type = imageDescriptor->type;
+ Sampler samplerState = {};
+ samplerState.textureType = type;
+ samplerState.textureFormat = imageDescriptor->format;
- Sampler samplerState = {};
- samplerState.textureType = type;
- samplerState.textureFormat = imageDescriptor->format;
-
- samplerState.addressingModeU = convertAddressingMode(0, sampler, type);
- samplerState.addressingModeV = convertAddressingMode(1, sampler, type);
- samplerState.addressingModeW = convertAddressingMode(2, sampler, type);
- samplerState.addressingModeY = convertAddressingMode(3, sampler, type);
-
- samplerState.mipmapFilter = convertMipmapMode(sampler);
- samplerState.swizzle = imageDescriptor->swizzle;
- samplerState.gatherComponent = instruction.gatherComponent;
- samplerState.highPrecisionFiltering = false;
- samplerState.largeTexture = (imageDescriptor->extent.width > SHRT_MAX) ||
- (imageDescriptor->extent.height > SHRT_MAX) ||
- (imageDescriptor->extent.depth > SHRT_MAX);
-
- if(sampler)
- {
- samplerState.textureFilter = (instruction.samplerMethod == Gather) ? FILTER_GATHER : convertFilterMode(sampler);
- samplerState.border = sampler->borderColor;
+ samplerState.addressingModeU = convertAddressingMode(0, sampler, type);
+ samplerState.addressingModeV = convertAddressingMode(1, sampler, type);
+ samplerState.addressingModeW = convertAddressingMode(2, sampler, type);
+ samplerState.addressingModeY = convertAddressingMode(3, sampler, type);
samplerState.mipmapFilter = convertMipmapMode(sampler);
+ samplerState.swizzle = imageDescriptor->swizzle;
+ samplerState.gatherComponent = instruction.gatherComponent;
+ samplerState.highPrecisionFiltering = false;
+ samplerState.largeTexture = (imageDescriptor->extent.width > SHRT_MAX) ||
+ (imageDescriptor->extent.height > SHRT_MAX) ||
+ (imageDescriptor->extent.depth > SHRT_MAX);
- samplerState.compareEnable = (sampler->compareEnable != VK_FALSE);
- samplerState.compareOp = sampler->compareOp;
- samplerState.unnormalizedCoordinates = (sampler->unnormalizedCoordinates != VK_FALSE);
+ if(sampler)
+ {
+ samplerState.textureFilter = (instruction.samplerMethod == Gather) ? FILTER_GATHER : convertFilterMode(sampler);
+ samplerState.border = sampler->borderColor;
- samplerState.ycbcrModel = sampler->ycbcrModel;
- samplerState.studioSwing = sampler->studioSwing;
- samplerState.swappedChroma = sampler->swappedChroma;
+ samplerState.mipmapFilter = convertMipmapMode(sampler);
- samplerState.mipLodBias = sampler->mipLodBias;
- samplerState.maxAnisotropy = sampler->maxAnisotropy;
- samplerState.minLod = sampler->minLod;
- samplerState.maxLod = sampler->maxLod;
- }
+ samplerState.compareEnable = (sampler->compareEnable != VK_FALSE);
+ samplerState.compareOp = sampler->compareOp;
+ samplerState.unnormalizedCoordinates = (sampler->unnormalizedCoordinates != VK_FALSE);
- routine = emitSamplerRoutine(instruction, samplerState);
+ samplerState.ycbcrModel = sampler->ycbcrModel;
+ samplerState.studioSwing = sampler->studioSwing;
+ samplerState.swappedChroma = sampler->swappedChroma;
- cache->add(key, routine);
+ samplerState.mipLodBias = sampler->mipLodBias;
+ samplerState.maxAnisotropy = sampler->maxAnisotropy;
+ samplerState.minLod = sampler->minLod;
+ samplerState.maxLod = sampler->maxLod;
+ }
+
+ return emitSamplerRoutine(instruction, samplerState);
+ };
+
+ auto routine = cache->getOrCreate(key, createSamplingRoutine);
+
return (ImageSampler *)(routine->getEntry());
}
diff --git a/src/System/Debug.cpp b/src/System/Debug.cpp
index 1b91e14..df7ab45 100644
--- a/src/System/Debug.cpp
+++ b/src/System/Debug.cpp
@@ -14,11 +14,6 @@
#include "Debug.hpp"
-#include <atomic>
-#include <cstdarg>
-#include <cstdio>
-#include <string>
-
#if __ANDROID__
# include <android/log.h>
#endif
@@ -34,6 +29,11 @@
# include <unistd.h>
#endif
+#include <atomic>
+#include <cstdarg>
+#include <cstdio>
+#include <string>
+
#ifdef ERROR
# undef ERROR // b/127920555
#endif
diff --git a/src/Vulkan/VkDevice.cpp b/src/Vulkan/VkDevice.cpp
index 492c676..982c10a 100644
--- a/src/Vulkan/VkDevice.cpp
+++ b/src/Vulkan/VkDevice.cpp
@@ -38,17 +38,6 @@
namespace vk {
-std::shared_ptr<rr::Routine> Device::SamplingRoutineCache::query(const vk::Device::SamplingRoutineCache::Key &key) const
-{
- return cache.query(key);
-}
-
-void Device::SamplingRoutineCache::add(const vk::Device::SamplingRoutineCache::Key &key, const std::shared_ptr<rr::Routine> &routine)
-{
- ASSERT(routine);
- cache.add(key, routine);
-}
-
rr::Routine *Device::SamplingRoutineCache::querySnapshot(const vk::Device::SamplingRoutineCache::Key &key) const
{
return cache.querySnapshot(key).get();
@@ -56,6 +45,8 @@
void Device::SamplingRoutineCache::updateSnapshot()
{
+ std::lock_guard<std::mutex> lock(mutex);
+
cache.updateSnapshot();
}
@@ -309,15 +300,9 @@
void Device::updateSamplingRoutineSnapshotCache()
{
- std::unique_lock<std::mutex> lock(samplingRoutineCacheMutex);
samplingRoutineCache->updateSnapshot();
}
-std::mutex &Device::getSamplingRoutineCacheMutex()
-{
- return samplingRoutineCacheMutex;
-}
-
uint32_t Device::indexSampler(const SamplerState &samplerState)
{
return samplerIndexer->index(samplerState);
diff --git a/src/Vulkan/VkDevice.hpp b/src/Vulkan/VkDevice.hpp
index 2a52473..3ba442d 100644
--- a/src/Vulkan/VkDevice.hpp
+++ b/src/Vulkan/VkDevice.hpp
@@ -86,18 +86,31 @@
};
};
- std::shared_ptr<rr::Routine> query(const Key &key) const;
- void add(const Key &key, const std::shared_ptr<rr::Routine> &routine);
+ template<typename Function>
+ std::shared_ptr<rr::Routine> getOrCreate(const Key &key, Function createRoutine)
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+
+ if(auto existingRoutine = cache.query(key))
+ {
+ return existingRoutine;
+ }
+
+ std::shared_ptr<rr::Routine> newRoutine = createRoutine(key);
+ cache.add(key, newRoutine);
+
+ return newRoutine;
+ }
rr::Routine *querySnapshot(const Key &key) const;
void updateSnapshot();
private:
- sw::LRUSnapshotCache<Key, std::shared_ptr<rr::Routine>, Key::Hash> cache;
+ sw::LRUSnapshotCache<Key, std::shared_ptr<rr::Routine>, Key::Hash> cache; // guarded by mutex
+ std::mutex mutex;
};
SamplingRoutineCache *getSamplingRoutineCache() const;
- std::mutex &getSamplingRoutineCacheMutex();
rr::Routine *querySnapshotCache(const SamplingRoutineCache::Key &key) const;
void updateSamplingRoutineSnapshotCache();
@@ -139,14 +152,13 @@
Queue *const queues = nullptr;
uint32_t queueCount = 0;
std::unique_ptr<sw::Blitter> blitter;
- std::unique_ptr<SamplingRoutineCache> samplingRoutineCache;
- std::mutex samplingRoutineCacheMutex;
uint32_t enabledExtensionCount = 0;
typedef char ExtensionName[VK_MAX_EXTENSION_NAME_SIZE];
ExtensionName *extensions = nullptr;
const VkPhysicalDeviceFeatures enabledFeatures = {};
std::shared_ptr<marl::Scheduler> scheduler;
+ std::unique_ptr<SamplingRoutineCache> samplingRoutineCache;
std::unique_ptr<SamplerIndexer> samplerIndexer;
#ifdef ENABLE_VK_DEBUGGER