Просмотр исходного кода

video_core: Abstract vk_sampler_cache into a templated class

ReinUsesLisp 7 лет назад
Родитель
Сommit
c5047540c9

+ 2 - 0
src/video_core/CMakeLists.txt

@@ -67,6 +67,8 @@ add_library(video_core STATIC
     renderer_opengl/renderer_opengl.h
     renderer_opengl/renderer_opengl.h
     renderer_opengl/utils.cpp
     renderer_opengl/utils.cpp
     renderer_opengl/utils.h
     renderer_opengl/utils.h
+    sampler_cache.cpp
+    sampler_cache.h
     shader/decode/arithmetic.cpp
     shader/decode/arithmetic.cpp
     shader/decode/arithmetic_immediate.cpp
     shader/decode/arithmetic_immediate.cpp
     shader/decode/bfe.cpp
     shader/decode/bfe.cpp

+ 12 - 28
src/video_core/renderer_vulkan/vk_sampler_cache.cpp

@@ -7,7 +7,6 @@
 #include <unordered_map>
 #include <unordered_map>
 
 
 #include "common/assert.h"
 #include "common/assert.h"
-#include "common/cityhash.h"
 #include "video_core/renderer_vulkan/declarations.h"
 #include "video_core/renderer_vulkan/declarations.h"
 #include "video_core/renderer_vulkan/maxwell_to_vk.h"
 #include "video_core/renderer_vulkan/maxwell_to_vk.h"
 #include "video_core/renderer_vulkan/vk_sampler_cache.h"
 #include "video_core/renderer_vulkan/vk_sampler_cache.h"
@@ -28,39 +27,20 @@ static std::optional<vk::BorderColor> TryConvertBorderColor(std::array<float, 4>
     }
     }
 }
 }
 
 
-std::size_t SamplerCacheKey::Hash() const {
-    static_assert(sizeof(raw) % sizeof(u64) == 0);
-    return static_cast<std::size_t>(
-        Common::CityHash64(reinterpret_cast<const char*>(raw.data()), sizeof(raw) / sizeof(u64)));
-}
-
-bool SamplerCacheKey::operator==(const SamplerCacheKey& rhs) const {
-    return raw == rhs.raw;
-}
-
 VKSamplerCache::VKSamplerCache(const VKDevice& device) : device{device} {}
 VKSamplerCache::VKSamplerCache(const VKDevice& device) : device{device} {}
 
 
 VKSamplerCache::~VKSamplerCache() = default;
 VKSamplerCache::~VKSamplerCache() = default;
 
 
-vk::Sampler VKSamplerCache::GetSampler(const Tegra::Texture::TSCEntry& tsc) {
-    const auto [entry, is_cache_miss] = cache.try_emplace(SamplerCacheKey{tsc});
-    auto& sampler = entry->second;
-    if (is_cache_miss) {
-        sampler = CreateSampler(tsc);
-    }
-    return *sampler;
-}
-
-UniqueSampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc) {
-    const float max_anisotropy = tsc.GetMaxAnisotropy();
-    const bool has_anisotropy = max_anisotropy > 1.0f;
+UniqueSampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc) const {
+    const float max_anisotropy{tsc.GetMaxAnisotropy()};
+    const bool has_anisotropy{max_anisotropy > 1.0f};
 
 
-    const auto border_color = tsc.GetBorderColor();
-    const auto vk_border_color = TryConvertBorderColor(border_color);
+    const auto border_color{tsc.GetBorderColor()};
+    const auto vk_border_color{TryConvertBorderColor(border_color)};
     UNIMPLEMENTED_IF_MSG(!vk_border_color, "Unimplemented border color {} {} {} {}",
     UNIMPLEMENTED_IF_MSG(!vk_border_color, "Unimplemented border color {} {} {} {}",
                          border_color[0], border_color[1], border_color[2], border_color[3]);
                          border_color[0], border_color[1], border_color[2], border_color[3]);
 
 
-    constexpr bool unnormalized_coords = false;
+    constexpr bool unnormalized_coords{false};
 
 
     const vk::SamplerCreateInfo sampler_ci(
     const vk::SamplerCreateInfo sampler_ci(
         {}, MaxwellToVK::Sampler::Filter(tsc.mag_filter),
         {}, MaxwellToVK::Sampler::Filter(tsc.mag_filter),
@@ -73,9 +53,13 @@ UniqueSampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc)
         tsc.GetMaxLod(), vk_border_color.value_or(vk::BorderColor::eFloatTransparentBlack),
         tsc.GetMaxLod(), vk_border_color.value_or(vk::BorderColor::eFloatTransparentBlack),
         unnormalized_coords);
         unnormalized_coords);
 
 
-    const auto& dld = device.GetDispatchLoader();
-    const auto dev = device.GetLogical();
+    const auto& dld{device.GetDispatchLoader()};
+    const auto dev{device.GetLogical()};
     return dev.createSamplerUnique(sampler_ci, nullptr, dld);
     return dev.createSamplerUnique(sampler_ci, nullptr, dld);
 }
 }
 
 
+vk::Sampler VKSamplerCache::ToSamplerType(const UniqueSampler& sampler) const {
+    return *sampler;
+}
+
 } // namespace Vulkan
 } // namespace Vulkan

+ 6 - 30
src/video_core/renderer_vulkan/vk_sampler_cache.h

@@ -8,49 +8,25 @@
 
 
 #include "common/common_types.h"
 #include "common/common_types.h"
 #include "video_core/renderer_vulkan/declarations.h"
 #include "video_core/renderer_vulkan/declarations.h"
+#include "video_core/sampler_cache.h"
 #include "video_core/textures/texture.h"
 #include "video_core/textures/texture.h"
 
 
 namespace Vulkan {
 namespace Vulkan {
 
 
 class VKDevice;
 class VKDevice;
 
 
-struct SamplerCacheKey final : public Tegra::Texture::TSCEntry {
-    std::size_t Hash() const;
-
-    bool operator==(const SamplerCacheKey& rhs) const;
-
-    bool operator!=(const SamplerCacheKey& rhs) const {
-        return !operator==(rhs);
-    }
-};
-
-} // namespace Vulkan
-
-namespace std {
-
-template <>
-struct hash<Vulkan::SamplerCacheKey> {
-    std::size_t operator()(const Vulkan::SamplerCacheKey& k) const noexcept {
-        return k.Hash();
-    }
-};
-
-} // namespace std
-
-namespace Vulkan {
-
-class VKSamplerCache {
+class VKSamplerCache final : public VideoCommon::SamplerCache<vk::Sampler, UniqueSampler> {
 public:
 public:
     explicit VKSamplerCache(const VKDevice& device);
     explicit VKSamplerCache(const VKDevice& device);
     ~VKSamplerCache();
     ~VKSamplerCache();
 
 
-    vk::Sampler GetSampler(const Tegra::Texture::TSCEntry& tsc);
+protected:
+    UniqueSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc) const;
 
 
-private:
-    UniqueSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc);
+    vk::Sampler ToSamplerType(const UniqueSampler& sampler) const;
 
 
+private:
     const VKDevice& device;
     const VKDevice& device;
-    std::unordered_map<SamplerCacheKey, UniqueSampler> cache;
 };
 };
 
 
 } // namespace Vulkan
 } // namespace Vulkan

+ 21 - 0
src/video_core/sampler_cache.cpp

@@ -0,0 +1,21 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/cityhash.h"
+#include "common/common_types.h"
+#include "video_core/sampler_cache.h"
+
+namespace VideoCommon {
+
+std::size_t SamplerCacheKey::Hash() const {
+    static_assert(sizeof(raw) % sizeof(u64) == 0);
+    return static_cast<std::size_t>(
+        Common::CityHash64(reinterpret_cast<const char*>(raw.data()), sizeof(raw) / sizeof(u64)));
+}
+
+bool SamplerCacheKey::operator==(const SamplerCacheKey& rhs) const {
+    return raw == rhs.raw;
+}
+
+} // namespace VideoCommon

+ 60 - 0
src/video_core/sampler_cache.h

@@ -0,0 +1,60 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <cstddef>
+#include <unordered_map>
+
+#include "video_core/textures/texture.h"
+
+namespace VideoCommon {
+
+struct SamplerCacheKey final : public Tegra::Texture::TSCEntry {
+    std::size_t Hash() const;
+
+    bool operator==(const SamplerCacheKey& rhs) const;
+
+    bool operator!=(const SamplerCacheKey& rhs) const {
+        return !operator==(rhs);
+    }
+};
+
+} // namespace VideoCommon
+
+namespace std {
+
+template <>
+struct hash<VideoCommon::SamplerCacheKey> {
+    std::size_t operator()(const VideoCommon::SamplerCacheKey& k) const noexcept {
+        return k.Hash();
+    }
+};
+
+} // namespace std
+
+namespace VideoCommon {
+
+template <typename SamplerType, typename SamplerStorageType>
+class SamplerCache {
+public:
+    SamplerType GetSampler(const Tegra::Texture::TSCEntry& tsc) {
+        const auto [entry, is_cache_miss] = cache.try_emplace(SamplerCacheKey{tsc});
+        auto& sampler = entry->second;
+        if (is_cache_miss) {
+            sampler = CreateSampler(tsc);
+        }
+        return ToSamplerType(sampler);
+    }
+
+protected:
+    virtual SamplerStorageType CreateSampler(const Tegra::Texture::TSCEntry& tsc) const = 0;
+
+    virtual SamplerType ToSamplerType(const SamplerStorageType& sampler) const = 0;
+
+private:
+    std::unordered_map<SamplerCacheKey, SamplerStorageType> cache;
+};
+
+} // namespace VideoCommon