From e2c76c4064d88e5f4048aaaeeab767f7ccc34b4b Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 7 Jul 2019 21:50:25 -0400 Subject: [PATCH] gl_shader_decompiler: Correct gl_FragCoord.x/y when render target is rescaled --- .../renderer_opengl/gl_rasterizer.cpp | 2 +- .../renderer_opengl/gl_shader_decompiler.cpp | 20 +++++++++++++------ .../renderer_opengl/gl_shader_manager.cpp | 6 +++++- .../renderer_opengl/gl_shader_manager.h | 7 ++++++- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 3dd1f5f82e..2ecb6c1cea 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -651,7 +651,7 @@ void RasterizerOpenGL::DrawPrelude() { SyncViewport(state, res_scaling); SyncScissorTest(state, res_scaling); - shader_program_manager->SetConstants(gpu); + shader_program_manager->SetConstants(gpu, res_scaling); shader_program_manager->ApplyTo(state); state.Apply(); diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 3a82556da7..0e66501273 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -943,12 +943,20 @@ private: case Attribute::Index::Position: switch (stage) { case ProgramType::Geometry: - return {fmt::format("gl_in[{}].gl_Position{}", Visit(buffer).AsUint(), - GetSwizzle(element)), - Type::Float}; - case ProgramType::Fragment: - return {element == 3 ? "1.0f" : ("gl_FragCoord"s + GetSwizzle(element)), - Type::Float}; + return fmt::format("gl_in[{}].gl_Position{}", Visit(buffer).AsUint(), + GetSwizzle(element)); + case ProgramType::Fragment: { + switch (element) { + case 0: + return "(gl_FragCoord.x / utof(config_pack[3]))"; + case 1: + return "(gl_FragCoord.y / utof(config_pack[3]))"; + case 2: + return "gl_FragCoord.z"; + case 3: + return "1.0f"; + } + } default: UNREACHABLE(); } diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index f179143cb3..d857f3771c 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp @@ -4,6 +4,7 @@ #include #include "common/common_types.h" +#include "core/settings.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/renderer_opengl/gl_shader_manager.h" @@ -37,7 +38,7 @@ ProgramManager::ProgramManager() { ProgramManager::~ProgramManager() = default; -void ProgramManager::SetConstants(Tegra::Engines::Maxwell3D& maxwell_3d) { +void ProgramManager::SetConstants(Tegra::Engines::Maxwell3D& maxwell_3d, bool rescaling) { const auto& regs = maxwell_3d.regs; const auto& state = maxwell_3d.state; @@ -61,6 +62,8 @@ void ProgramManager::SetConstants(Tegra::Engines::Maxwell3D& maxwell_3d) { // Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value. const GLfloat y_direction = regs.screen_y_control.y_negate == 0 ? 1.0f : -1.0f; + 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}) { if (!stage) { @@ -70,6 +73,7 @@ void ProgramManager::SetConstants(Tegra::Engines::Maxwell3D& maxwell_3d) { stage->SetFlipStage(flip_stage); stage->SetYDirection(y_direction); stage->SetViewportScale(flip_x, flip_y); + stage->SetRescalingFactor(rescale_factor); stage->UpdateConstants(); } } diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index b55b72f162..6ff58dc7d3 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h @@ -40,6 +40,10 @@ public: state.y_direction = y_direction; } + void SetRescalingFactor(GLfloat rescaling_factor) { + state.rescaling_factor = rescaling_factor; + } + void SetViewportScale(GLfloat x, GLfloat y) { state.viewport_scale = {x, y}; } @@ -52,6 +56,7 @@ private: GLuint instance_id; GLuint flip_stage; GLfloat y_direction; + GLfloat rescaling_factor; }; }; @@ -67,7 +72,7 @@ public: explicit ProgramManager(); ~ProgramManager(); - void SetConstants(Tegra::Engines::Maxwell3D& maxwell_3d); + void SetConstants(Tegra::Engines::Maxwell3D& maxwell_3d, bool rescaling); void ApplyTo(OpenGLState& state);