Texture_Cache: Corrections and fixes to resolution rescaler

This commit is contained in:
Fernando Sahmkow
2019-07-06 22:25:55 -04:00
committed by FernandoS27
parent 0a93394604
commit 28e9c792a8
5 changed files with 90 additions and 9 deletions

View File

@@ -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() {

View File

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

View File

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

View File

@@ -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{};
};

View File

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