Unravel Engine C++ Reference
Loading...
Searching...
No Matches
eviction_settings.cpp
Go to the documentation of this file.
1#include "eviction_settings.h"
2
3#include <graphics/eviction.h>
4#include <graphics/graphics.h>
5
6#include <algorithm>
7
8namespace unravel
9{
10namespace
11{
12auto clamp_u64(std::int64_t value) -> std::uint64_t
13{
14 return static_cast<std::uint64_t>(std::max<std::int64_t>(0, value));
15}
16
20auto manual_target_ratio(const eviction_settings& s) -> double
21{
22 if(s.budget_fraction <= 0.0f)
23 {
24 return 1.0;
25 }
26 const double ratio = static_cast<double>(s.target_fraction) / static_cast<double>(s.budget_fraction);
27 // Clamp into a sensible band; a configuration with target_fraction > budget_fraction is a
28 // user mistake but should not push target_bytes above soft_budget_bytes (the entire eviction
29 // policy assumes target <= soft).
30 return std::clamp(ratio, 0.1, 1.0);
31}
32
35auto safety_margin_for(std::uint64_t hard_limit_bytes) -> std::uint64_t
36{
37 constexpr std::uint64_t k_floor = std::uint64_t(64) * 1024 * 1024;
38 return std::max(k_floor, hard_limit_bytes / 50);
39}
40
48auto build_budget(const eviction_settings& settings, std::uint64_t gpu_max)
50{
52 if(settings.auto_budget && gpu_max > 0)
53 {
54 b.hard_limit_bytes = gpu_max;
55 b.soft_budget_bytes = static_cast<std::uint64_t>(static_cast<double>(gpu_max) * settings.budget_fraction);
56 b.target_bytes = static_cast<std::uint64_t>(static_cast<double>(gpu_max) * settings.target_fraction);
57 }
58 else
59 {
60 const std::uint64_t mb = clamp_u64(settings.manual_budget_mb) * 1024ull * 1024ull;
61 if(mb == 0)
62 {
63 return b; // hard_limit_bytes == 0 disables reclaim_for entirely.
64 }
65 b.hard_limit_bytes = mb;
66 b.soft_budget_bytes = mb;
67 b.target_bytes = static_cast<std::uint64_t>(static_cast<double>(mb) * manual_target_ratio(settings));
68 }
69 b.safety_margin_bytes = safety_margin_for(b.hard_limit_bytes);
70 return b;
71}
72} // namespace
73
75{
76 namespace ev = gfx::eviction;
77
78 if(!ev::is_supported())
79 {
80 return;
81 }
82
83 const auto* bx = gfx::get_stats();
84 const std::uint64_t gpu_max = (bx != nullptr) ? clamp_u64(bx->gpuMemoryMax) : 0;
85 const std::uint64_t gpu_used = (bx != nullptr) ? clamp_u64(bx->gpuMemoryUsed) : 0;
86
87 // Peek (do not consume) the bytes queued since the last bgfx::frame/flush. The backend's
88 // gpuMemoryUsed lags by a frame or more, so a burst of creates is invisible until later; the
89 // queued counter adds the in-flight bytes back into the prediction. It is cleared centrally by
90 // gfx::frames(), so this read must NOT drain it (reclaim_for and any other
91 // observers in the same frame all need to see the same number).
92 const std::uint64_t queued = ev::peek_queued_bytes();
93
94 const ev::budget_state budget = build_budget(settings, gpu_max);
95
96 // The metric we compare against the budget for the proactive sweep. In auto mode we treat
97 // gpu memory as ground truth, credit in-flight destroys, and include queued creates. In manual
98 // mode the user caps our own footprint: evictable resident bytes plus non-evictable in-flight
99 // creates (render targets) that are not tracked in the registry.
100 const std::uint64_t gross_auto = gpu_used + queued;
101 const std::uint64_t pending = ev::peek_pending_release_bytes();
102 const std::uint64_t used =
103 (settings.auto_budget && gpu_max > 0)
104 ? (gross_auto > pending ? gross_auto - pending : 0)
105 : (ev::get_stats().resident_bytes + ev::peek_external_queued_bytes());
106
107 // Publish the budget so reclaim_for and tooling see the same numbers.
108 ev::set_budget(budget, used);
109
110 if(!settings.enabled || used <= budget.soft_budget_bytes)
111 {
112 return;
113 }
114
115 const auto strat = static_cast<ev::strategy>(settings.strategy);
116 const auto min_age = static_cast<std::uint32_t>(std::max(0, settings.min_age_frames));
117 const auto max_evictions = (used > budget.hard_limit_bytes)
118 ? static_cast<std::uint32_t>(0)
119 : static_cast<std::uint32_t>(std::max(0, settings.max_evictions));
120 ev::evict_bytes(used - budget.target_bytes, strat, min_age, max_evictions);
121}
122
123} // namespace unravel
entt::handle b
Definition imgui.h:25
const stats * get_stats()
Definition graphics.cpp:450
void update_eviction(const eviction_settings &settings)
std::uint64_t safety_margin_bytes
Definition eviction.h:109