diff --git a/kraken/KRSampler.cpp b/kraken/KRSampler.cpp index 703ad3c..3bd69a9 100644 --- a/kraken/KRSampler.cpp +++ b/kraken/KRSampler.cpp @@ -30,8 +30,9 @@ // #include "KRSampler.h" +#include "KRSamplerManager.h" -KRSampler::KRSampler(KRContext& context, KRSurface& surface, const SamplerInfo& info) +KRSampler::KRSampler(KRContext& context, const SamplerInfo& info) : KRContextObject(context) { // TODO - Implement stub function diff --git a/kraken/KRSampler.h b/kraken/KRSampler.h index 0c2f574..22c8e5c 100644 --- a/kraken/KRSampler.h +++ b/kraken/KRSampler.h @@ -34,19 +34,14 @@ #include "KREngine-common.h" #include "KRContextObject.h" -#include "KRSurface.h" -class SamplerInfo -{ -public: - VkSamplerCreateInfo createInfo; -}; +class SamplerInfo; class KRSampler : public KRContextObject { public: - KRSampler(KRContext& context, KRSurface& surface, const SamplerInfo& info); + KRSampler(KRContext& context, const SamplerInfo& info); virtual ~KRSampler(); VkSampler& getSampler(); diff --git a/kraken/KRSamplerManager.cpp b/kraken/KRSamplerManager.cpp index 4f4a98c..42f4b04 100644 --- a/kraken/KRSamplerManager.cpp +++ b/kraken/KRSamplerManager.cpp @@ -33,19 +33,32 @@ #include "KRSamplerManager.h" +// TODO - Purge samplers that are not used for several frames + +bool SamplerInfo::operator==(const SamplerInfo& rhs) const +{ + assert(rhs.createInfo.pNext == nullptr); + assert(createInfo.pNext == nullptr); + // Compare the contents of the SamplerInfo struct, ignoring the first two members (sType, pNext) + return memcmp(&rhs.createInfo.flags, &createInfo.flags, sizeof(createInfo) - size_t(&createInfo.flags) - size_t(&createInfo)); +} + KRSamplerManager::KRSamplerManager(KRContext& context) : KRContextObject(context) { - // TODO - Implement stub function } KRSamplerManager::~KRSamplerManager() { - // TODO - Implement stub function } -KRSampler* KRSamplerManager::getSampler(KRSurface& surface, const SamplerInfo& info) +KRSampler* KRSamplerManager::getSampler(const SamplerInfo& info) { - // TODO - Implement stub function - return nullptr; + SamplerMap::iterator itr = m_samplers.find(info); + if (itr != m_samplers.end()) { + return itr->second; + } + KRSampler* sampler = new KRSampler(getContext(), info); + m_samplers.emplace(info, sampler); + return sampler; } diff --git a/kraken/KRSamplerManager.h b/kraken/KRSamplerManager.h index 70d43d7..13233f4 100644 --- a/kraken/KRSamplerManager.h +++ b/kraken/KRSamplerManager.h @@ -40,19 +40,32 @@ using std::vector; #include "KRSampler.h" -class KRSampler; -class SamplerInfo; +class SamplerInfo +{ +public: + VkSamplerCreateInfo createInfo; + bool operator==(const SamplerInfo& rhs) const; +}; + +struct SamplerInfoHasher +{ + std::size_t operator()(const SamplerInfo& s) const + { + // Compute a hash using the most commonly used sampler fields + // Collisions are okay, but we need to balance cost of creating + // hashes with cost of resolving collisions. + return std::hash{}(static_cast((s.createInfo.flags))); + } +}; class KRSamplerManager : public KRContextObject { public: - KRSamplerManager(KRContext& context); virtual ~KRSamplerManager(); - KRSampler* getSampler(KRSurface& surface, const SamplerInfo& info); - + KRSampler* getSampler(const SamplerInfo& info); private: - typedef std::map >, KRSampler*> SamplerMap; + typedef std::unordered_map SamplerMap; SamplerMap m_samplers; };