diff options
| author | 2019-04-02 15:54:11 -0300 | |
|---|---|---|
| committer | 2019-04-02 15:54:11 -0300 | |
| commit | c5047540c9c3f807ed2164b938898ffff27f53bc (patch) | |
| tree | 317395c2df72428942d25ac3d185d763cb52972d /src | |
| parent | Merge pull request #2316 from ReinUsesLisp/fixup-process (diff) | |
| download | yuzu-c5047540c9c3f807ed2164b938898ffff27f53bc.tar.gz yuzu-c5047540c9c3f807ed2164b938898ffff27f53bc.tar.xz yuzu-c5047540c9c3f807ed2164b938898ffff27f53bc.zip | |
video_core: Abstract vk_sampler_cache into a templated class
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_sampler_cache.cpp | 40 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_sampler_cache.h | 36 | ||||
| -rw-r--r-- | src/video_core/sampler_cache.cpp | 21 | ||||
| -rw-r--r-- | src/video_core/sampler_cache.h | 60 |
5 files changed, 101 insertions, 58 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 14b76680f..1a0cc6df1 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -67,6 +67,8 @@ add_library(video_core STATIC | |||
| 67 | renderer_opengl/renderer_opengl.h | 67 | renderer_opengl/renderer_opengl.h |
| 68 | renderer_opengl/utils.cpp | 68 | renderer_opengl/utils.cpp |
| 69 | renderer_opengl/utils.h | 69 | renderer_opengl/utils.h |
| 70 | sampler_cache.cpp | ||
| 71 | sampler_cache.h | ||
| 70 | shader/decode/arithmetic.cpp | 72 | shader/decode/arithmetic.cpp |
| 71 | shader/decode/arithmetic_immediate.cpp | 73 | shader/decode/arithmetic_immediate.cpp |
| 72 | shader/decode/bfe.cpp | 74 | shader/decode/bfe.cpp |
diff --git a/src/video_core/renderer_vulkan/vk_sampler_cache.cpp b/src/video_core/renderer_vulkan/vk_sampler_cache.cpp index ed3178f09..801826d3d 100644 --- a/src/video_core/renderer_vulkan/vk_sampler_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_sampler_cache.cpp | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | #include <unordered_map> | 7 | #include <unordered_map> |
| 8 | 8 | ||
| 9 | #include "common/assert.h" | 9 | #include "common/assert.h" |
| 10 | #include "common/cityhash.h" | ||
| 11 | #include "video_core/renderer_vulkan/declarations.h" | 10 | #include "video_core/renderer_vulkan/declarations.h" |
| 12 | #include "video_core/renderer_vulkan/maxwell_to_vk.h" | 11 | #include "video_core/renderer_vulkan/maxwell_to_vk.h" |
| 13 | #include "video_core/renderer_vulkan/vk_sampler_cache.h" | 12 | #include "video_core/renderer_vulkan/vk_sampler_cache.h" |
| @@ -28,39 +27,20 @@ static std::optional<vk::BorderColor> TryConvertBorderColor(std::array<float, 4> | |||
| 28 | } | 27 | } |
| 29 | } | 28 | } |
| 30 | 29 | ||
| 31 | std::size_t SamplerCacheKey::Hash() const { | ||
| 32 | static_assert(sizeof(raw) % sizeof(u64) == 0); | ||
| 33 | return static_cast<std::size_t>( | ||
| 34 | Common::CityHash64(reinterpret_cast<const char*>(raw.data()), sizeof(raw) / sizeof(u64))); | ||
| 35 | } | ||
| 36 | |||
| 37 | bool SamplerCacheKey::operator==(const SamplerCacheKey& rhs) const { | ||
| 38 | return raw == rhs.raw; | ||
| 39 | } | ||
| 40 | |||
| 41 | VKSamplerCache::VKSamplerCache(const VKDevice& device) : device{device} {} | 30 | VKSamplerCache::VKSamplerCache(const VKDevice& device) : device{device} {} |
| 42 | 31 | ||
| 43 | VKSamplerCache::~VKSamplerCache() = default; | 32 | VKSamplerCache::~VKSamplerCache() = default; |
| 44 | 33 | ||
| 45 | vk::Sampler VKSamplerCache::GetSampler(const Tegra::Texture::TSCEntry& tsc) { | 34 | UniqueSampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc) const { |
| 46 | const auto [entry, is_cache_miss] = cache.try_emplace(SamplerCacheKey{tsc}); | 35 | const float max_anisotropy{tsc.GetMaxAnisotropy()}; |
| 47 | auto& sampler = entry->second; | 36 | const bool has_anisotropy{max_anisotropy > 1.0f}; |
| 48 | if (is_cache_miss) { | ||
| 49 | sampler = CreateSampler(tsc); | ||
| 50 | } | ||
| 51 | return *sampler; | ||
| 52 | } | ||
| 53 | |||
| 54 | UniqueSampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc) { | ||
| 55 | const float max_anisotropy = tsc.GetMaxAnisotropy(); | ||
| 56 | const bool has_anisotropy = max_anisotropy > 1.0f; | ||
| 57 | 37 | ||
| 58 | const auto border_color = tsc.GetBorderColor(); | 38 | const auto border_color{tsc.GetBorderColor()}; |
| 59 | const auto vk_border_color = TryConvertBorderColor(border_color); | 39 | const auto vk_border_color{TryConvertBorderColor(border_color)}; |
| 60 | UNIMPLEMENTED_IF_MSG(!vk_border_color, "Unimplemented border color {} {} {} {}", | 40 | UNIMPLEMENTED_IF_MSG(!vk_border_color, "Unimplemented border color {} {} {} {}", |
| 61 | border_color[0], border_color[1], border_color[2], border_color[3]); | 41 | border_color[0], border_color[1], border_color[2], border_color[3]); |
| 62 | 42 | ||
| 63 | constexpr bool unnormalized_coords = false; | 43 | constexpr bool unnormalized_coords{false}; |
| 64 | 44 | ||
| 65 | const vk::SamplerCreateInfo sampler_ci( | 45 | const vk::SamplerCreateInfo sampler_ci( |
| 66 | {}, MaxwellToVK::Sampler::Filter(tsc.mag_filter), | 46 | {}, MaxwellToVK::Sampler::Filter(tsc.mag_filter), |
| @@ -73,9 +53,13 @@ UniqueSampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc) | |||
| 73 | tsc.GetMaxLod(), vk_border_color.value_or(vk::BorderColor::eFloatTransparentBlack), | 53 | tsc.GetMaxLod(), vk_border_color.value_or(vk::BorderColor::eFloatTransparentBlack), |
| 74 | unnormalized_coords); | 54 | unnormalized_coords); |
| 75 | 55 | ||
| 76 | const auto& dld = device.GetDispatchLoader(); | 56 | const auto& dld{device.GetDispatchLoader()}; |
| 77 | const auto dev = device.GetLogical(); | 57 | const auto dev{device.GetLogical()}; |
| 78 | return dev.createSamplerUnique(sampler_ci, nullptr, dld); | 58 | return dev.createSamplerUnique(sampler_ci, nullptr, dld); |
| 79 | } | 59 | } |
| 80 | 60 | ||
| 61 | vk::Sampler VKSamplerCache::ToSamplerType(const UniqueSampler& sampler) const { | ||
| 62 | return *sampler; | ||
| 63 | } | ||
| 64 | |||
| 81 | } // namespace Vulkan | 65 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_sampler_cache.h b/src/video_core/renderer_vulkan/vk_sampler_cache.h index c6394dc87..771b05c73 100644 --- a/src/video_core/renderer_vulkan/vk_sampler_cache.h +++ b/src/video_core/renderer_vulkan/vk_sampler_cache.h | |||
| @@ -8,49 +8,25 @@ | |||
| 8 | 8 | ||
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "video_core/renderer_vulkan/declarations.h" | 10 | #include "video_core/renderer_vulkan/declarations.h" |
| 11 | #include "video_core/sampler_cache.h" | ||
| 11 | #include "video_core/textures/texture.h" | 12 | #include "video_core/textures/texture.h" |
| 12 | 13 | ||
| 13 | namespace Vulkan { | 14 | namespace Vulkan { |
| 14 | 15 | ||
| 15 | class VKDevice; | 16 | class VKDevice; |
| 16 | 17 | ||
| 17 | struct SamplerCacheKey final : public Tegra::Texture::TSCEntry { | 18 | class VKSamplerCache final : public VideoCommon::SamplerCache<vk::Sampler, UniqueSampler> { |
| 18 | std::size_t Hash() const; | ||
| 19 | |||
| 20 | bool operator==(const SamplerCacheKey& rhs) const; | ||
| 21 | |||
| 22 | bool operator!=(const SamplerCacheKey& rhs) const { | ||
| 23 | return !operator==(rhs); | ||
| 24 | } | ||
| 25 | }; | ||
| 26 | |||
| 27 | } // namespace Vulkan | ||
| 28 | |||
| 29 | namespace std { | ||
| 30 | |||
| 31 | template <> | ||
| 32 | struct hash<Vulkan::SamplerCacheKey> { | ||
| 33 | std::size_t operator()(const Vulkan::SamplerCacheKey& k) const noexcept { | ||
| 34 | return k.Hash(); | ||
| 35 | } | ||
| 36 | }; | ||
| 37 | |||
| 38 | } // namespace std | ||
| 39 | |||
| 40 | namespace Vulkan { | ||
| 41 | |||
| 42 | class VKSamplerCache { | ||
| 43 | public: | 19 | public: |
| 44 | explicit VKSamplerCache(const VKDevice& device); | 20 | explicit VKSamplerCache(const VKDevice& device); |
| 45 | ~VKSamplerCache(); | 21 | ~VKSamplerCache(); |
| 46 | 22 | ||
| 47 | vk::Sampler GetSampler(const Tegra::Texture::TSCEntry& tsc); | 23 | protected: |
| 24 | UniqueSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc) const; | ||
| 48 | 25 | ||
| 49 | private: | 26 | vk::Sampler ToSamplerType(const UniqueSampler& sampler) const; |
| 50 | UniqueSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc); | ||
| 51 | 27 | ||
| 28 | private: | ||
| 52 | const VKDevice& device; | 29 | const VKDevice& device; |
| 53 | std::unordered_map<SamplerCacheKey, UniqueSampler> cache; | ||
| 54 | }; | 30 | }; |
| 55 | 31 | ||
| 56 | } // namespace Vulkan | 32 | } // namespace Vulkan |
diff --git a/src/video_core/sampler_cache.cpp b/src/video_core/sampler_cache.cpp new file mode 100644 index 000000000..53c7ef12d --- /dev/null +++ b/src/video_core/sampler_cache.cpp | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/cityhash.h" | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "video_core/sampler_cache.h" | ||
| 8 | |||
| 9 | namespace VideoCommon { | ||
| 10 | |||
| 11 | std::size_t SamplerCacheKey::Hash() const { | ||
| 12 | static_assert(sizeof(raw) % sizeof(u64) == 0); | ||
| 13 | return static_cast<std::size_t>( | ||
| 14 | Common::CityHash64(reinterpret_cast<const char*>(raw.data()), sizeof(raw) / sizeof(u64))); | ||
| 15 | } | ||
| 16 | |||
| 17 | bool SamplerCacheKey::operator==(const SamplerCacheKey& rhs) const { | ||
| 18 | return raw == rhs.raw; | ||
| 19 | } | ||
| 20 | |||
| 21 | } // namespace VideoCommon | ||
diff --git a/src/video_core/sampler_cache.h b/src/video_core/sampler_cache.h new file mode 100644 index 000000000..cbe3ad071 --- /dev/null +++ b/src/video_core/sampler_cache.h | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <cstddef> | ||
| 8 | #include <unordered_map> | ||
| 9 | |||
| 10 | #include "video_core/textures/texture.h" | ||
| 11 | |||
| 12 | namespace VideoCommon { | ||
| 13 | |||
| 14 | struct SamplerCacheKey final : public Tegra::Texture::TSCEntry { | ||
| 15 | std::size_t Hash() const; | ||
| 16 | |||
| 17 | bool operator==(const SamplerCacheKey& rhs) const; | ||
| 18 | |||
| 19 | bool operator!=(const SamplerCacheKey& rhs) const { | ||
| 20 | return !operator==(rhs); | ||
| 21 | } | ||
| 22 | }; | ||
| 23 | |||
| 24 | } // namespace VideoCommon | ||
| 25 | |||
| 26 | namespace std { | ||
| 27 | |||
| 28 | template <> | ||
| 29 | struct hash<VideoCommon::SamplerCacheKey> { | ||
| 30 | std::size_t operator()(const VideoCommon::SamplerCacheKey& k) const noexcept { | ||
| 31 | return k.Hash(); | ||
| 32 | } | ||
| 33 | }; | ||
| 34 | |||
| 35 | } // namespace std | ||
| 36 | |||
| 37 | namespace VideoCommon { | ||
| 38 | |||
| 39 | template <typename SamplerType, typename SamplerStorageType> | ||
| 40 | class SamplerCache { | ||
| 41 | public: | ||
| 42 | SamplerType GetSampler(const Tegra::Texture::TSCEntry& tsc) { | ||
| 43 | const auto [entry, is_cache_miss] = cache.try_emplace(SamplerCacheKey{tsc}); | ||
| 44 | auto& sampler = entry->second; | ||
| 45 | if (is_cache_miss) { | ||
| 46 | sampler = CreateSampler(tsc); | ||
| 47 | } | ||
| 48 | return ToSamplerType(sampler); | ||
| 49 | } | ||
| 50 | |||
| 51 | protected: | ||
| 52 | virtual SamplerStorageType CreateSampler(const Tegra::Texture::TSCEntry& tsc) const = 0; | ||
| 53 | |||
| 54 | virtual SamplerType ToSamplerType(const SamplerStorageType& sampler) const = 0; | ||
| 55 | |||
| 56 | private: | ||
| 57 | std::unordered_map<SamplerCacheKey, SamplerStorageType> cache; | ||
| 58 | }; | ||
| 59 | |||
| 60 | } // namespace VideoCommon \ No newline at end of file | ||