aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache/texture_cache.h
diff options
context:
space:
mode:
authorCamilleLaVey <camillelavey99@gmail.com>2026-01-11 05:31:23 +0100
committercrueter <crueter@eden-emu.dev>2026-01-11 05:31:23 +0100
commita27d35362d288b9af6c76cadec664e9453a9d237 (patch)
tree7f8ec123f9b0a04994fdc6e558c1a5a954f0adbe /src/video_core/texture_cache/texture_cache.h
parenta2236c1a430b643ed981877a7af19a3360d017f1 (diff)
[vk, qcom] Memory, Samplers, BindingBuffers and UniformBufferAlignment set by hardware capabilities for QCOM. (#3280)
This PR adjust resources usage of Eden based on driver specification, improving stability and smarter resources usage, extends the amount of TotalPipelineWorkers on Android. Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3280 Reviewed-by: Lizzie <lizzie@eden-emu.dev> Reviewed-by: DraVee <dravee@eden-emu.dev> Co-authored-by: CamilleLaVey <camillelavey99@gmail.com> Co-committed-by: CamilleLaVey <camillelavey99@gmail.com>
Diffstat (limited to 'src/video_core/texture_cache/texture_cache.h')
-rw-r--r--src/video_core/texture_cache/texture_cache.h80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 2a44a5e8b2..c580fb10ef 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -6,6 +6,8 @@
#pragma once
+#include <limits>
+#include <optional>
#include <unordered_set>
#include <boost/container/small_vector.hpp>
@@ -1736,12 +1738,90 @@ SamplerId TextureCache<P>::FindSampler(const TSCEntry& config) {
}
const auto [pair, is_new] = channel_state->samplers.try_emplace(config);
if (is_new) {
+ EnforceSamplerBudget();
pair->second = slot_samplers.insert(runtime, config);
}
return pair->second;
}
template <class P>
+std::optional<size_t> TextureCache<P>::QuerySamplerBudget() const {
+ if constexpr (requires { runtime.GetSamplerHeapBudget(); }) {
+ return runtime.GetSamplerHeapBudget();
+ } else {
+ return std::nullopt;
+ }
+}
+
+template <class P>
+void TextureCache<P>::EnforceSamplerBudget() {
+ const auto budget = QuerySamplerBudget();
+ if (!budget) {
+ return;
+ }
+ if (slot_samplers.size() < *budget) {
+ return;
+ }
+ if (!channel_state) {
+ return;
+ }
+ if (last_sampler_gc_frame == frame_tick) {
+ return;
+ }
+ last_sampler_gc_frame = frame_tick;
+ TrimInactiveSamplers(*budget);
+}
+
+template <class P>
+void TextureCache<P>::TrimInactiveSamplers(size_t budget) {
+ if (channel_state->samplers.empty()) {
+ return;
+ }
+ static constexpr size_t SAMPLER_GC_SLACK = 1024;
+ auto mark_active = [](auto& set, SamplerId id) {
+ if (!id || id == CORRUPT_ID || id == NULL_SAMPLER_ID) {
+ return;
+ }
+ set.insert(id);
+ };
+ std::unordered_set<SamplerId> active;
+ active.reserve(channel_state->graphics_sampler_ids.size() +
+ channel_state->compute_sampler_ids.size());
+ for (const SamplerId id : channel_state->graphics_sampler_ids) {
+ mark_active(active, id);
+ }
+ for (const SamplerId id : channel_state->compute_sampler_ids) {
+ mark_active(active, id);
+ }
+
+ size_t removed = 0;
+ auto& sampler_map = channel_state->samplers;
+ for (auto it = sampler_map.begin(); it != sampler_map.end();) {
+ const SamplerId sampler_id = it->second;
+ if (!sampler_id || sampler_id == CORRUPT_ID) {
+ it = sampler_map.erase(it);
+ continue;
+ }
+ if (active.find(sampler_id) != active.end()) {
+ ++it;
+ continue;
+ }
+ slot_samplers.erase(sampler_id);
+ it = sampler_map.erase(it);
+ ++removed;
+ if (slot_samplers.size() + SAMPLER_GC_SLACK <= budget) {
+ break;
+ }
+ }
+
+ if (removed != 0) {
+ LOG_WARNING(HW_GPU,
+ "Sampler cache exceeded {} entries on this driver; reclaimed {} inactive samplers",
+ budget, removed);
+ }
+}
+
+template <class P>
ImageViewId TextureCache<P>::FindColorBuffer(size_t index) {
const auto& regs = maxwell3d->regs;
if (index >= regs.rt_control.count) {