Texture_Cache: Corrections and fixes to resolution rescaler
This commit is contained in:
committed by
FernandoS27
parent
0a93394604
commit
28e9c792a8
@@ -375,6 +375,7 @@ void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
|
||||
void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||
const VideoCore::DiskResourceLoadCallback& callback) {
|
||||
shader_cache.LoadDiskCache(stop_loading, callback);
|
||||
texture_cache.LoadResources();
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::ConfigureFramebuffers() {
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <fmt/format.h>
|
||||
#include <json.hpp>
|
||||
|
||||
#include "common/assert.h"
|
||||
@@ -18,13 +20,48 @@ namespace VideoCommon::Resolution {
|
||||
using namespace nlohmann;
|
||||
|
||||
ScalingDatabase::ScalingDatabase(Core::System& system) : database{}, blacklist{}, system{system} {
|
||||
title_id = system.CurrentProcess()->GetTitleID();
|
||||
title_id = 0;
|
||||
}
|
||||
|
||||
ScalingDatabase::~ScalingDatabase() {
|
||||
SaveDatabase();
|
||||
}
|
||||
|
||||
void ScalingDatabase::Init() {
|
||||
title_id = system.CurrentProcess()->GetTitleID();
|
||||
LoadDatabase();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void ScalingDatabase::LoadDatabase() {
|
||||
const std::string path = GetProfilePath();
|
||||
bool exists = FileUtil::Exists(path);
|
||||
if (!exists) {
|
||||
return;
|
||||
}
|
||||
std::ifstream file(path);
|
||||
json in;
|
||||
file >> in;
|
||||
u32 version = in["version"].get<u32>();
|
||||
if (version != DBVersion) {
|
||||
return;
|
||||
}
|
||||
for (const auto& entry : in["entries"]) {
|
||||
ResolutionKey key{};
|
||||
key.format = static_cast<PixelFormat>(entry["format"].get<u32>());
|
||||
key.width = entry["width"].get<u32>();
|
||||
key.height = entry["height"].get<u32>();
|
||||
database.emplace(key, true);
|
||||
}
|
||||
for (const auto& entry : in["blacklist"]) {
|
||||
ResolutionKey key{};
|
||||
key.format = static_cast<PixelFormat>(entry["format"].get<u32>());
|
||||
key.width = entry["width"].get<u32>();
|
||||
key.height = entry["height"].get<u32>();
|
||||
blacklist.insert(key);
|
||||
}
|
||||
}
|
||||
|
||||
void ScalingDatabase::SaveDatabase() {
|
||||
json out;
|
||||
out["version"] = DBVersion;
|
||||
@@ -40,7 +77,17 @@ void ScalingDatabase::SaveDatabase() {
|
||||
}
|
||||
}
|
||||
out["entries"] = std::move(entries);
|
||||
std::ofstream file(GetProfilePath());
|
||||
auto blacklist_entries = json::array();
|
||||
for (const auto& key : blacklist) {
|
||||
blacklist_entries.push_back({
|
||||
{"format", static_cast<u32>(key.format)},
|
||||
{"width", key.width},
|
||||
{"height", key.height},
|
||||
});
|
||||
}
|
||||
out["blacklist"] = blacklist_entries;
|
||||
const std::string path = GetProfilePath();
|
||||
std::ofstream file(path);
|
||||
file << std::setw(4) << out << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,12 +52,19 @@ public:
|
||||
~ScalingDatabase();
|
||||
|
||||
void SaveDatabase();
|
||||
void LoadDatabase();
|
||||
void Init();
|
||||
|
||||
bool IsInDatabase(const PixelFormat format, const u32 width, const u32 height) {
|
||||
ResolutionKey key{format, width, height};
|
||||
return database.count(key) > 0;
|
||||
}
|
||||
|
||||
bool IsBlacklisted(const PixelFormat format, const u32 width, const u32 height) {
|
||||
ResolutionKey key{format, width, height};
|
||||
return blacklist.count(key) > 0;
|
||||
}
|
||||
|
||||
void MarkRendered(const PixelFormat format, const u32 width, const u32 height);
|
||||
void Register(const PixelFormat format, const u32 width, const u32 height);
|
||||
void Unregister(const PixelFormat format, const u32 width, const u32 height);
|
||||
@@ -68,6 +75,7 @@ public:
|
||||
private:
|
||||
std::unordered_map<ResolutionKey, bool> database;
|
||||
std::unordered_set<ResolutionKey> blacklist;
|
||||
bool initialized{};
|
||||
u64 title_id;
|
||||
Core::System& system;
|
||||
|
||||
|
||||
@@ -207,6 +207,11 @@ public:
|
||||
|
||||
void MarkAsRescaled(const bool is_rescaled) {
|
||||
this->is_rescaled = is_rescaled;
|
||||
this->is_rescale_candidate = is_rescaled;
|
||||
}
|
||||
|
||||
void MarkAsRescaleCandidate(const bool is_rescale_candidate) {
|
||||
this->is_rescale_candidate = is_rescale_candidate;
|
||||
}
|
||||
|
||||
void MarkAsPicked(bool is_picked_) {
|
||||
@@ -234,6 +239,10 @@ public:
|
||||
return is_rescaled;
|
||||
}
|
||||
|
||||
bool IsRescaleCandidate() const {
|
||||
return is_rescale_candidate;
|
||||
}
|
||||
|
||||
bool IsRegistered() const {
|
||||
return is_registered;
|
||||
}
|
||||
@@ -327,6 +336,7 @@ private:
|
||||
bool is_registered{};
|
||||
bool is_picked{};
|
||||
bool is_rescaled{};
|
||||
bool is_rescale_candidate{};
|
||||
u32 index{NO_RT};
|
||||
u64 modification_tick{};
|
||||
};
|
||||
|
||||
@@ -71,6 +71,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void LoadResources() {
|
||||
scaling_database.Init();
|
||||
}
|
||||
|
||||
/***
|
||||
* `Guard` guarantees that rendertargets don't unregister themselves if the
|
||||
* collide. Protection is currently only done on 3D slices.
|
||||
@@ -163,6 +167,7 @@ public:
|
||||
if (depth_buffer.target) {
|
||||
depth_buffer.target->MarkAsRenderTarget(true, DEPTH_RT);
|
||||
if (IsResScannerEnabled()) {
|
||||
MarkScanner(depth_buffer.target);
|
||||
MarkScannerRender(depth_buffer.target);
|
||||
}
|
||||
}
|
||||
@@ -201,6 +206,7 @@ public:
|
||||
if (render_targets[index].target) {
|
||||
render_targets[index].target->MarkAsRenderTarget(true, static_cast<u32>(index));
|
||||
if (IsResScannerEnabled()) {
|
||||
MarkScanner(render_targets[index].target);
|
||||
MarkScannerRender(render_targets[index].target);
|
||||
}
|
||||
}
|
||||
@@ -282,7 +288,7 @@ public:
|
||||
for (const auto& target : render_targets) {
|
||||
if (target.target) {
|
||||
enabled_targets++;
|
||||
if (target.target->IsRescaled()) {
|
||||
if (target.target->IsRescaleCandidate()) {
|
||||
rescaling = true;
|
||||
rescaled_targets++;
|
||||
}
|
||||
@@ -290,7 +296,7 @@ public:
|
||||
}
|
||||
if (depth_buffer.target) {
|
||||
enabled_targets++;
|
||||
if (depth_buffer.target->IsRescaled()) {
|
||||
if (depth_buffer.target->IsRescaleCandidate()) {
|
||||
rescaling = true;
|
||||
rescaled_targets++;
|
||||
}
|
||||
@@ -374,9 +380,6 @@ protected:
|
||||
gpu_addr);
|
||||
return;
|
||||
}
|
||||
if (IsResScannerEnabled()) {
|
||||
MarkScanner(surface);
|
||||
}
|
||||
const bool continuous = system.GPU().MemoryManager().IsBlockContinuous(gpu_addr, size);
|
||||
surface->MarkAsContinuous(continuous);
|
||||
surface->SetCacheAddr(cache_ptr);
|
||||
@@ -427,10 +430,14 @@ protected:
|
||||
// Must be called by child's create surface
|
||||
void SignalCreatedSurface(TSurface& new_surface) {
|
||||
const auto& params = new_surface->GetSurfaceParams();
|
||||
if (guard_render_targets && EnabledRescaling()) {
|
||||
if (EnabledRescaling()) {
|
||||
if (scaling_database.IsInDatabase(params.pixel_format, params.width, params.height)) {
|
||||
new_surface->MarkAsRescaled(true);
|
||||
}
|
||||
} else if (IsResScannerEnabled()) {
|
||||
if (scaling_database.IsInDatabase(params.pixel_format, params.width, params.height)) {
|
||||
new_surface->MarkAsRescaleCandidate(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,7 +733,7 @@ private:
|
||||
|
||||
// If none are found, we are done. we just load the surface and create it.
|
||||
if (overlaps.empty()) {
|
||||
return InitializeSurface(gpu_addr, params, preserve_contents);
|
||||
return InitializeSurface(gpu_addr, params, preserve_contents && !is_render);
|
||||
}
|
||||
|
||||
// Step 3
|
||||
@@ -925,6 +932,9 @@ private:
|
||||
}
|
||||
|
||||
void LoadSurface(const TSurface& surface) {
|
||||
if (IsResScannerEnabled()) {
|
||||
UnmarkScanner(surface);
|
||||
}
|
||||
staging_cache.GetBuffer(0).resize(surface->GetHostSizeInBytes());
|
||||
surface->LoadBuffer(system.GPU().MemoryManager(), staging_cache);
|
||||
surface->UploadTexture(staging_cache.GetBuffer(0));
|
||||
@@ -1031,6 +1041,11 @@ private:
|
||||
scaling_database.Register(params.pixel_format, params.width, params.height);
|
||||
}
|
||||
|
||||
bool IsBlackListed(const TSurface& surface) {
|
||||
const auto params = surface->GetSurfaceParams();
|
||||
return scaling_database.IsBlackListed(params.pixel_format, params.width, params.height);
|
||||
}
|
||||
|
||||
void MarkScannerRender(const TSurface& surface) {
|
||||
const auto params = surface->GetSurfaceParams();
|
||||
scaling_database.MarkRendered(params.pixel_format, params.width, params.height);
|
||||
|
||||
Reference in New Issue
Block a user