Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Native Resolution Rescaling #2860

Open
wants to merge 24 commits into
base: master
from

Conversation

@FernandoS27
Copy link
Contributor

@FernandoS27 FernandoS27 commented Sep 15, 2019

Native Resolution Rescaling in Emulators used to be an almost trivial process for old console GPUs where only 1 render target existed, memory wasn't unified (in the GPU sense, not on SoC sense) and textures weren't anywhere as complex as they are now. Native Resolution Rescaling for a modern GPU as Maxwell 2nd Gen is quite a challenge due to many factors: More complex texture types can be partially or entirely rendered onto: Cube textures, Array Textures, 3d Textures, etc; 8 different render targets with shared viewports and scissor tests, unified memories with uncalled readbacks and hardcoded shaders created for fixed resolutions (glFragCoord & TexelFetch). This PR introduces a set of heuristics and mechanisms to detect possible candidate render targets for rescaling based on a simple evolutive AI algorithm and performs render target rescaling based on a generated database of rescalable rendertargets (rescale profile) plus its corrections on state and shader code.

@FernandoS27 FernandoS27 force-pushed the FernandoS27:resolution-rescaling-4 branch from 2752580 to 77742bf Sep 16, 2019
@@ -772,6 +768,11 @@ void RasterizerOpenGL::DrawArrays() {
gpu.dirty.ResetVertexArrays();
}

bool res_scaling = texture_cache.IsResolutionScalingEnabled();

This comment has been minimized.

@ReinUsesLisp

ReinUsesLisp Sep 18, 2019
Contributor

const

const auto& regs = system.GPU().Maxwell3D().regs;
const bool geometry_shaders_enabled =
regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
const std::size_t viewport_count =
geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
float factor = rescaling ? Settings::values.resolution_factor : 1.0;

This comment has been minimized.

@ReinUsesLisp

ReinUsesLisp Sep 18, 2019
Contributor

const and 1.0f
resolution_factor should be changed to be an integer, since we don't plan to support downscaling.

const auto& regs = system.GPU().Maxwell3D().regs;
const bool geometry_shaders_enabled =
regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
const std::size_t viewport_count =
geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
float factor = rescaling ? Settings::values.resolution_factor : 1.0;

This comment has been minimized.

@ReinUsesLisp

ReinUsesLisp Sep 18, 2019
Contributor

Ditto.

dst.y = src.min_y;
dst.width = width;
dst.height = height;
dst.x = src.min_x * factor;

This comment has been minimized.

@ReinUsesLisp

ReinUsesLisp Sep 18, 2019
Contributor

If resolution_factor type is not changed, this will signal warnings about implicitly converting float to T, enclose with a static_cast<u32>(...)

@@ -156,7 +156,7 @@ class RasterizerOpenGL : public VideoCore::RasterizerInterface {
const GLShader::ImageEntry& entry);

/// Syncs the viewport and depth range to match the guest state
void SyncViewport(OpenGLState& current_state);
void SyncViewport(OpenGLState& current_state, bool rescaling = false);

This comment has been minimized.

@ReinUsesLisp

ReinUsesLisp Sep 18, 2019
Contributor

Don't use an optional parameter here, it is be dangerous not to keep in mind that rescaling is enabled.

std::unordered_set<ResolutionKey> database;
std::unordered_set<ResolutionKey> blacklist;
bool initialized{};
u64 title_id;

This comment has been minimized.

@ReinUsesLisp

ReinUsesLisp Sep 18, 2019
Contributor

Zero initialize this with {}.

for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
SetEmptyColorBuffer(i);
}

enable_resolution_scaling =
Settings::values.resolution_factor != 1.0 && !Settings::values.use_resolution_scanner;

This comment has been minimized.

@ReinUsesLisp

ReinUsesLisp Sep 18, 2019
Contributor

Change 1.0 to 1 if resolution_factor type is changed, otherwise use 1.0f instead.

// Must be called by child's create surface
void SignalCreatedSurface(TSurface& new_surface) {
if (EnabledRescaling()) {
if (IsInRSDatabase(new_surface)) {

This comment has been minimized.

@ReinUsesLisp

ReinUsesLisp Sep 18, 2019
Contributor

Use && with the previous ìf

@@ -567,6 +567,10 @@ void Config::ReadRendererValues() {
ReadSetting(QStringLiteral("use_accurate_gpu_emulation"), false).toBool();
Settings::values.use_asynchronous_gpu_emulation =
ReadSetting(QStringLiteral("use_asynchronous_gpu_emulation"), false).toBool();
Settings::values.use_resolution_scanner =
ReadSetting(QStringLiteral("use_resolution_scanner"), false).toBool();
Settings::values.use_resolution_scanner =

This comment has been minimized.

@ReinUsesLisp

ReinUsesLisp Sep 18, 2019
Contributor

Rebase typo? This is being set twice.

// OS we just open the transferable shader cache folder without preselecting the transferable
// shader cache file for the selected game.
#if defined(Q_OS_WIN)
const QString explorer = QStringLiteral("explorer");

This comment has been minimized.

@ReinUsesLisp

ReinUsesLisp Sep 18, 2019
Contributor

We should have a function for doing this. This code is copied and pasted from somewhere else.

@ReinUsesLisp
Copy link
Contributor

@ReinUsesLisp ReinUsesLisp commented Sep 18, 2019

I dislike using uniform constants, but it's the sanest solution we have.

std::unordered_set<ResolutionKey> database;
std::unordered_set<ResolutionKey> blacklist;
std::unordered_set<ResolutionKey> database{};
std::unordered_set<ResolutionKey> blacklist{};

This comment has been minimized.

@ReinUsesLisp

ReinUsesLisp Sep 19, 2019
Contributor

These {} are not needed. std::unordered_set has a constructor.

using Tegra::Engines::Maxwell3D;
using Maxwell = Tegra::Engines::Maxwell3D::Regs;

enum ProgramLocations : u32 {

This comment has been minimized.

@lioncash

lioncash Sep 19, 2019
Contributor

This can be relocated into UpdateConstants to keep their scope to their only usage area.

const GLfloat rescale_factor = rescaling ? Settings::values.resolution_factor : 1.0f;

for (const auto stage :
std::array{current_state.vertex, current_state.geometry, current_state.fragment}) {

This comment has been minimized.

@lioncash

lioncash Sep 19, 2019
Contributor

You should be able to do this with a normal initializer list like:

Suggested change
std::array{current_state.vertex, current_state.geometry, current_state.fragment}) {
for (const auto stage : {current_state.vertex, current_state.geometry, current_state.fragment}) {
struct {
GLuint instance_id;
GLuint flip_stage;
GLfloat y_direction;

This comment has been minimized.

@lioncash

lioncash Sep 19, 2019
Contributor

It's undefined behavior to access this and the rescaling factor if any of the other fields are accessed, since they don't have a common type.

return FileUtil::GetUserPath(FileUtil::UserPath::RescalingDir);
}

ScalingDatabase::ScalingDatabase(Core::System& system) : database{}, blacklist{}, system{system} {

This comment has been minimized.

@lioncash

lioncash Sep 19, 2019
Contributor

Suggested change
ScalingDatabase::ScalingDatabase(Core::System& system) : database{}, blacklist{}, system{system} {
ScalingDatabase::ScalingDatabase(Core::System& system) : system{system} {

These types already have a constructor

}

ScalingDatabase::ScalingDatabase(Core::System& system) : database{}, blacklist{}, system{system} {
title_id = 0;

This comment has been minimized.

@lioncash

lioncash Sep 19, 2019
Contributor

This is already initialized within the class declaration itself, so it can be removed.

void Init();

bool IsInDatabase(const PixelFormat format, const u32 width, const u32 height) {
ResolutionKey key{format, width, height};

This comment has been minimized.

@lioncash

lioncash Sep 19, 2019
Contributor

This can be a const member function.

return database.count(key) > 0;
}

bool IsBlacklisted(const PixelFormat format, const u32 width, const u32 height) {

This comment has been minimized.

@lioncash

lioncash Sep 19, 2019
Contributor

Ditto

return enable_resolution_scaling;
}

bool IsResScannerEnabled() const {

This comment has been minimized.

@lioncash

lioncash Sep 19, 2019
Contributor

Suggested change
bool IsResScannerEnabled() const {
bool IsResolutionScannerEnabled() const {

Res is easily confused with other names (e.g. Resource), It's also inconsistent with naming elsewhere in the codebase (IsResolutionScalingEnabled, etc)

scaling_database.Register(params.pixel_format, params.width, params.height);
}

bool IsRSBlacklisted(const TSurface& surface) {

This comment has been minimized.

@lioncash

lioncash Sep 19, 2019
Contributor

This can be a const member function

return scaling_database.IsBlacklisted(params.pixel_format, params.width, params.height);
}

bool IsInRSDatabase(const TSurface& surface) {

This comment has been minimized.

@lioncash

lioncash Sep 19, 2019
Contributor

Ditto

@ogniK5377
Copy link
Contributor

@ogniK5377 ogniK5377 commented Sep 21, 2019

Reminder to address issues @FernandoS27

@FernandoS27 FernandoS27 force-pushed the FernandoS27:resolution-rescaling-4 branch from 8afd738 to 552f4a8 Sep 22, 2019
@FernandoS27
Copy link
Contributor Author

@FernandoS27 FernandoS27 commented Sep 22, 2019

@ogniK5377 Done, a few things weren't possible due to the lack of flexibility in json API.

@CLAassistant
Copy link

@CLAassistant CLAassistant commented Sep 30, 2019

CLA assistant check
All committers have signed the CLA.

@FernandoS27 FernandoS27 force-pushed the FernandoS27:resolution-rescaling-4 branch 2 times, most recently from 95116e5 to e6ab6eb Oct 4, 2019
@FernandoS27 FernandoS27 force-pushed the FernandoS27:resolution-rescaling-4 branch from e6ab6eb to 8cf23ad Oct 5, 2019
FernandoS27 and others added 20 commits Jul 6, 2019
…s scaling on imasge blit, image copy and buffer copy
Explicit locations break Intel and AMD's proprietary drivers. Use
glGetUniformLocation and implicit locations instead.
@FernandoS27 FernandoS27 force-pushed the FernandoS27:resolution-rescaling-4 branch from 8cf23ad to 4096dc7 Oct 5, 2019
@losh11
Copy link

@losh11 losh11 commented Sep 26, 2020

Wondering why this was never merged?

@renA21
Copy link

@renA21 renA21 commented Oct 6, 2020

Wondering why this was never merged?

Read the PSA here: https://yuzu-emu.org/help/feature/resolution-rescaler/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

9 participants
You can’t perform that action at this time.