yuzu-emu
/
yuzu
Archived
1
0
Fork 0

video_core: Abstract vk_sampler_cache into a templated class

This commit is contained in:
ReinUsesLisp 2019-04-02 15:54:11 -03:00
parent 628153cccd
commit c5047540c9
5 changed files with 101 additions and 58 deletions

View File

@ -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

View File

@ -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) { UniqueSampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc) const {
const auto [entry, is_cache_miss] = cache.try_emplace(SamplerCacheKey{tsc}); const float max_anisotropy{tsc.GetMaxAnisotropy()};
auto& sampler = entry->second; const bool has_anisotropy{max_anisotropy > 1.0f};
if (is_cache_miss) {
sampler = CreateSampler(tsc);
}
return *sampler;
}
UniqueSampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc) { const auto border_color{tsc.GetBorderColor()};
const float max_anisotropy = tsc.GetMaxAnisotropy(); const auto vk_border_color{TryConvertBorderColor(border_color)};
const bool has_anisotropy = max_anisotropy > 1.0f;
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& dld{device.GetDispatchLoader()};
const auto dev = device.GetLogical(); 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

View File

@ -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 { class VKSamplerCache final : public VideoCommon::SamplerCache<vk::Sampler, UniqueSampler> {
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 {
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;
vk::Sampler ToSamplerType(const UniqueSampler& sampler) const;
private: private:
UniqueSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc);
const VKDevice& device; const VKDevice& device;
std::unordered_map<SamplerCacheKey, UniqueSampler> cache;
}; };
} // namespace Vulkan } // namespace Vulkan

View File

@ -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

View File

@ -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