Commit 73c4a0c5 by Nicolas Capens Committed by Nicolas Capens

Uniquely identify sampler state

To avoid re-generating sampling routines for sampler with identical state, keep a map of sampler state to 32-bit integer identifiers. Bug: b/151235334 Change-Id: I105151675afbf29bd29585e866b8cd976f66fb49 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/42468 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent f948cd1e
...@@ -59,6 +59,44 @@ void Device::SamplingRoutineCache::updateConstCache() ...@@ -59,6 +59,44 @@ void Device::SamplingRoutineCache::updateConstCache()
cache.updateConstCache(); cache.updateConstCache();
} }
Device::SamplerIndexer::~SamplerIndexer()
{
ASSERT(map.empty());
}
uint32_t Device::SamplerIndexer::index(const SamplerState &samplerState)
{
std::lock_guard<std::mutex> lock(mutex);
auto it = map.find(samplerState);
if(it != map.end())
{
it->second.count++;
return it->second.id;
}
nextID++;
map.emplace(samplerState, Identifier{ nextID, 1 });
return nextID;
}
void Device::SamplerIndexer::remove(const SamplerState &samplerState)
{
std::lock_guard<std::mutex> lock(mutex);
auto it = map.find(samplerState);
ASSERT(it != map.end());
auto count = --it->second.count;
if(count == 0)
{
map.erase(it);
}
}
Device::Device(const VkDeviceCreateInfo *pCreateInfo, void *mem, PhysicalDevice *physicalDevice, const VkPhysicalDeviceFeatures *enabledFeatures, const std::shared_ptr<marl::Scheduler> &scheduler) Device::Device(const VkDeviceCreateInfo *pCreateInfo, void *mem, PhysicalDevice *physicalDevice, const VkPhysicalDeviceFeatures *enabledFeatures, const std::shared_ptr<marl::Scheduler> &scheduler)
: physicalDevice(physicalDevice) : physicalDevice(physicalDevice)
, queues(reinterpret_cast<Queue *>(mem)) , queues(reinterpret_cast<Queue *>(mem))
...@@ -99,6 +137,7 @@ Device::Device(const VkDeviceCreateInfo *pCreateInfo, void *mem, PhysicalDevice ...@@ -99,6 +137,7 @@ Device::Device(const VkDeviceCreateInfo *pCreateInfo, void *mem, PhysicalDevice
// FIXME (b/119409619): use an allocator here so we can control all memory allocations // FIXME (b/119409619): use an allocator here so we can control all memory allocations
blitter.reset(new sw::Blitter()); blitter.reset(new sw::Blitter());
samplingRoutineCache.reset(new SamplingRoutineCache()); samplingRoutineCache.reset(new SamplingRoutineCache());
samplerIndexer.reset(new SamplerIndexer());
#ifdef ENABLE_VK_DEBUGGER #ifdef ENABLE_VK_DEBUGGER
static auto port = getenv("VK_DEBUGGER_PORT"); static auto port = getenv("VK_DEBUGGER_PORT");
...@@ -279,4 +318,14 @@ std::mutex &Device::getSamplingRoutineCacheMutex() ...@@ -279,4 +318,14 @@ std::mutex &Device::getSamplingRoutineCacheMutex()
return samplingRoutineCacheMutex; return samplingRoutineCacheMutex;
} }
uint32_t Device::indexSampler(const SamplerState &samplerState)
{
return samplerIndexer->index(samplerState);
}
void Device::removeSampler(const SamplerState &samplerState)
{
samplerIndexer->remove(samplerState);
}
} // namespace vk } // namespace vk
...@@ -16,8 +16,11 @@ ...@@ -16,8 +16,11 @@
#define VK_DEVICE_HPP_ #define VK_DEVICE_HPP_
#include "VkObject.hpp" #include "VkObject.hpp"
#include "VkSampler.hpp"
#include "Device/LRUCache.hpp" #include "Device/LRUCache.hpp"
#include "Reactor/Routine.hpp" #include "Reactor/Routine.hpp"
#include <map>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
...@@ -98,6 +101,30 @@ public: ...@@ -98,6 +101,30 @@ public:
rr::Routine *findInConstCache(const SamplingRoutineCache::Key &key) const; rr::Routine *findInConstCache(const SamplingRoutineCache::Key &key) const;
void updateSamplingRoutineConstCache(); void updateSamplingRoutineConstCache();
class SamplerIndexer
{
public:
~SamplerIndexer();
uint32_t index(const SamplerState &samplerState);
void remove(const SamplerState &samplerState);
private:
struct Identifier
{
uint32_t id;
uint32_t count; // Number of samplers sharing this state identifier.
};
std::map<SamplerState, Identifier> map; // guarded by mutex
std::mutex mutex;
uint32_t nextID = 0;
};
uint32_t indexSampler(const SamplerState &samplerState);
void removeSampler(const SamplerState &samplerState);
std::shared_ptr<vk::dbg::Context> getDebuggerContext() const std::shared_ptr<vk::dbg::Context> getDebuggerContext() const
{ {
#ifdef ENABLE_VK_DEBUGGER #ifdef ENABLE_VK_DEBUGGER
...@@ -118,7 +145,9 @@ private: ...@@ -118,7 +145,9 @@ private:
typedef char ExtensionName[VK_MAX_EXTENSION_NAME_SIZE]; typedef char ExtensionName[VK_MAX_EXTENSION_NAME_SIZE];
ExtensionName *extensions = nullptr; ExtensionName *extensions = nullptr;
const VkPhysicalDeviceFeatures enabledFeatures = {}; const VkPhysicalDeviceFeatures enabledFeatures = {};
std::shared_ptr<marl::Scheduler> scheduler; std::shared_ptr<marl::Scheduler> scheduler;
std::unique_ptr<SamplerIndexer> samplerIndexer;
#ifdef ENABLE_VK_DEBUGGER #ifdef ENABLE_VK_DEBUGGER
struct struct
......
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
namespace vk { namespace vk {
std::atomic<uint32_t> Sampler::nextID(1);
SamplerState::SamplerState(const VkSamplerCreateInfo *pCreateInfo, const vk::SamplerYcbcrConversion *ycbcrConversion) SamplerState::SamplerState(const VkSamplerCreateInfo *pCreateInfo, const vk::SamplerYcbcrConversion *ycbcrConversion)
: Memset(this, 0) : Memset(this, 0)
, magFilter(pCreateInfo->magFilter) , magFilter(pCreateInfo->magFilter)
...@@ -44,8 +42,9 @@ SamplerState::SamplerState(const VkSamplerCreateInfo *pCreateInfo, const vk::Sam ...@@ -44,8 +42,9 @@ SamplerState::SamplerState(const VkSamplerCreateInfo *pCreateInfo, const vk::Sam
} }
} }
Sampler::Sampler(const VkSamplerCreateInfo *pCreateInfo, void *mem, const vk::SamplerYcbcrConversion *ycbcrConversion) Sampler::Sampler(const VkSamplerCreateInfo *pCreateInfo, void *mem, const SamplerState &samplerState, uint32_t samplerID)
: SamplerState(pCreateInfo, ycbcrConversion) : SamplerState(samplerState)
, id(samplerID)
{ {
} }
......
...@@ -58,17 +58,14 @@ struct SamplerState : sw::Memset<SamplerState> ...@@ -58,17 +58,14 @@ struct SamplerState : sw::Memset<SamplerState>
class Sampler : public Object<Sampler, VkSampler>, public SamplerState class Sampler : public Object<Sampler, VkSampler>, public SamplerState
{ {
public: public:
Sampler(const VkSamplerCreateInfo *pCreateInfo, void *mem, const vk::SamplerYcbcrConversion *ycbcrConversion); Sampler(const VkSamplerCreateInfo *pCreateInfo, void *mem, const SamplerState &samplerState, uint32_t samplerID);
static size_t ComputeRequiredAllocationSize(const VkSamplerCreateInfo *pCreateInfo) static size_t ComputeRequiredAllocationSize(const VkSamplerCreateInfo *pCreateInfo)
{ {
return 0; return 0;
} }
const uint32_t id = nextID++; const uint32_t id = 0;
private:
static std::atomic<uint32_t> nextID;
}; };
class SamplerYcbcrConversion : public Object<SamplerYcbcrConversion, VkSamplerYcbcrConversion> class SamplerYcbcrConversion : public Object<SamplerYcbcrConversion, VkSamplerYcbcrConversion>
......
...@@ -1857,7 +1857,18 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerC ...@@ -1857,7 +1857,18 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerC
extensionCreateInfo = extensionCreateInfo->pNext; extensionCreateInfo = extensionCreateInfo->pNext;
} }
return vk::Sampler::Create(pAllocator, pCreateInfo, pSampler, ycbcrConversion); vk::SamplerState samplerState(pCreateInfo, ycbcrConversion);
uint32_t samplerID = vk::Cast(device)->indexSampler(samplerState);
VkResult result = vk::Sampler::Create(pAllocator, pCreateInfo, pSampler, samplerState, samplerID);
if(*pSampler == VK_NULL_HANDLE)
{
ASSERT(result != VK_SUCCESS);
vk::Cast(device)->removeSampler(samplerState);
}
return result;
} }
VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator) VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator)
...@@ -1865,7 +1876,12 @@ VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler, ...@@ -1865,7 +1876,12 @@ VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler,
TRACE("(VkDevice device = %p, VkSampler sampler = %p, const VkAllocationCallbacks* pAllocator = %p)", TRACE("(VkDevice device = %p, VkSampler sampler = %p, const VkAllocationCallbacks* pAllocator = %p)",
device, static_cast<void *>(sampler), pAllocator); device, static_cast<void *>(sampler), pAllocator);
vk::destroy(sampler, pAllocator); if(sampler != VK_NULL_HANDLE)
{
vk::Cast(device)->removeSampler(*vk::Cast(sampler));
vk::destroy(sampler, pAllocator);
}
} }
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout) VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout)
......
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