Texture_Cache: Implement rescaled surface loading.

This commit is contained in:
Fernando Sahmkow
2019-07-07 13:43:41 -04:00
committed by FernandoS27
parent 36af7c6a36
commit f3777b5697
2 changed files with 66 additions and 6 deletions

View File

@@ -547,7 +547,12 @@ void RasterizerOpenGL::Clear() {
ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil);
bool res_scaling = texture_cache.IsResolutionScalingEnabled();
bool res_scaling;
if (use_color) {
res_scaling = texture_cache.IsResolutionScalingEnabledRT(regs.clear_buffers.RT);
} else {
res_scaling = texture_cache.IsResolutionScalingEnabledDB();
}
SyncViewport(clear_state, res_scaling);
if (regs.clear_flags.scissor) {

View File

@@ -12,6 +12,7 @@
#include <tuple>
#include <unordered_map>
#include <vector>
#include <fmt/format.h>
#include <boost/icl/interval_map.hpp>
#include <boost/range/iterator_range.hpp>
@@ -291,6 +292,26 @@ public:
return CheckResolutionScalingEnabled();
}
bool IsResolutionScalingEnabledRT(const std::size_t index) {
if (!EnabledRescaling()) {
return false;
}
if (render_targets[index].target) {
return render_targets[index].target->IsRescaled();
}
return false;
}
bool IsResolutionScalingEnabledDB() {
if (!EnabledRescaling()) {
return false;
}
if (depth_buffer.target) {
return depth_buffer.target->IsRescaled();
}
return false;
}
protected:
TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer)
: system{system}, rasterizer{rasterizer}, scaling_database{system} {
@@ -298,6 +319,9 @@ protected:
SetEmptyColorBuffer(i);
}
enable_resolution_scaling =
Settings::values.resolution_factor != 1.0 && !Settings::values.use_resolution_scanner;
SetEmptyDepthBuffer();
staging_cache.SetSize(2);
@@ -910,9 +934,29 @@ private:
return {new_surface, new_surface->GetMainView()};
}
void LoadSurface(const TSurface& surface) {
if (IsResScannerEnabled()) {
UnmarkScanner(surface);
void LoadSurfaceRescaled(TSurface& surface) {
const auto& params = surface->GetSurfaceParams();
enable_resolution_scaling = false;
TSurface proxy = CreateSurface(surface->GetGpuAddr(), params);
enable_resolution_scaling = true;
staging_cache.GetBuffer(0).resize(proxy->GetHostSizeInBytes());
proxy->LoadBuffer(system.GPU().MemoryManager(), staging_cache);
proxy->UploadTexture(staging_cache.GetBuffer(0));
Tegra::Engines::Fermi2D::Config copy_config;
const Common::Rectangle<u32> rect{0, 0, params.width, params.height};
copy_config.operation = Tegra::Engines::Fermi2D::Operation::SrcCopy;
copy_config.filter = Tegra::Engines::Fermi2D::Filter::Linear;
copy_config.src_rect = rect;
copy_config.dst_rect = rect;
TView src_view = proxy->GetMainView();
TView dst_view = surface->GetMainView();
ImageBlit(src_view, dst_view, copy_config);
}
void LoadSurface(TSurface& surface) {
if (surface->IsRescaled()) {
LoadSurfaceRescaled(surface);
return;
}
staging_cache.GetBuffer(0).resize(surface->GetHostSizeInBytes());
surface->LoadBuffer(system.GPU().MemoryManager(), staging_cache);
@@ -998,8 +1042,7 @@ private:
}
bool EnabledRescaling() const {
return Settings::values.resolution_factor != 1.0 &&
!Settings::values.use_resolution_scanner;
return enable_resolution_scaling;
}
bool IsResScannerEnabled() const {
@@ -1047,14 +1090,25 @@ private:
}
if (black_list) {
if (black_listed != enabled_targets) {
std::string blacklist_msg{};
for (const auto& target : render_targets) {
if (target.target) {
UnmarkScanner(target.target);
const auto& params = target.target->GetSurfaceParams();
blacklist_msg += fmt::format("Format:{}, Height:{}, Width:{}\n",
static_cast<u32>(params.pixel_format),
params.height, params.width);
}
}
if (depth_buffer.target) {
UnmarkScanner(depth_buffer.target);
const auto& params = depth_buffer.target->GetSurfaceParams();
blacklist_msg += fmt::format("Format:{}, Height:{}, Width:{}\n",
static_cast<u32>(params.pixel_format),
params.height, params.width);
}
LOG_CRITICAL(HW_GPU, "Scan detected a conflict:\n{}\nBlacklisting all",
blacklist_msg);
}
}
return false;
@@ -1107,6 +1161,7 @@ private:
// Guards the cache for protection conflicts.
bool guard_render_targets{};
bool guard_samplers{};
bool enable_resolution_scaling{};
// The siblings table is for formats that can inter exchange with one another
// without causing issues. This is only valid when a conflict occurs on a non