Merge pull request #4715 from iwubcode/efb_copy_corruption_at_higher_ir
Add configurable toggle to round vertices to nearest pixel
This commit is contained in:
commit
4c0a392698
|
@ -284,6 +284,10 @@ static wxString true_color_desc =
|
||||||
wxTRANSLATE("Forces the game to render the RGB color channels in 24-bit, thereby increasing "
|
wxTRANSLATE("Forces the game to render the RGB color channels in 24-bit, thereby increasing "
|
||||||
"quality by reducing color banding.\nIt has no impact on performance and causes "
|
"quality by reducing color banding.\nIt has no impact on performance and causes "
|
||||||
"few graphical issues.\n\n\nIf unsure, leave this checked.");
|
"few graphical issues.\n\n\nIf unsure, leave this checked.");
|
||||||
|
static wxString vertex_rounding_desc =
|
||||||
|
wxTRANSLATE("Round 2D vertices to whole pixels. Fixes some "
|
||||||
|
"games at higher internal resolutions. This setting is disabled and turned off "
|
||||||
|
"at 1x IR.\n\nIf unsure, leave this unchecked.");
|
||||||
static wxString gpu_texture_decoding_desc =
|
static wxString gpu_texture_decoding_desc =
|
||||||
wxTRANSLATE("Enables texture decoding using the GPU instead of the CPU. This may result in "
|
wxTRANSLATE("Enables texture decoding using the GPU instead of the CPU. This may result in "
|
||||||
"performance gains in some scenarios, or systems where the CPU is the bottleneck."
|
"performance gains in some scenarios, or systems where the CPU is the bottleneck."
|
||||||
|
@ -818,6 +822,10 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title)
|
||||||
szr_other->Add(CreateCheckBox(page_hacks, _("Disable Bounding Box"),
|
szr_other->Add(CreateCheckBox(page_hacks, _("Disable Bounding Box"),
|
||||||
wxGetTranslation(disable_bbox_desc), vconfig.bBBoxEnable,
|
wxGetTranslation(disable_bbox_desc), vconfig.bBBoxEnable,
|
||||||
true));
|
true));
|
||||||
|
vertex_rounding_checkbox =
|
||||||
|
CreateCheckBox(page_hacks, _("Vertex Rounding"), wxGetTranslation(vertex_rounding_desc),
|
||||||
|
vconfig.bVertexRounding);
|
||||||
|
szr_other->Add(vertex_rounding_checkbox);
|
||||||
|
|
||||||
wxStaticBoxSizer* const group_other =
|
wxStaticBoxSizer* const group_other =
|
||||||
new wxStaticBoxSizer(wxVERTICAL, page_hacks, _("Other"));
|
new wxStaticBoxSizer(wxVERTICAL, page_hacks, _("Other"));
|
||||||
|
|
|
@ -239,6 +239,17 @@ protected:
|
||||||
progressive_scan_checkbox->Disable();
|
progressive_scan_checkbox->Disable();
|
||||||
render_to_main_checkbox->Disable();
|
render_to_main_checkbox->Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't enable 'vertex rounding' at native
|
||||||
|
if (vconfig.iEFBScale == SCALE_1X)
|
||||||
|
{
|
||||||
|
vertex_rounding_checkbox->Enable(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vertex_rounding_checkbox->Enable(true);
|
||||||
|
}
|
||||||
|
|
||||||
ev.Skip();
|
ev.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,6 +297,7 @@ protected:
|
||||||
SettingCheckBox* cache_hires_textures;
|
SettingCheckBox* cache_hires_textures;
|
||||||
|
|
||||||
wxCheckBox* progressive_scan_checkbox;
|
wxCheckBox* progressive_scan_checkbox;
|
||||||
|
wxCheckBox* vertex_rounding_checkbox;
|
||||||
|
|
||||||
wxChoice* choice_ppshader;
|
wxChoice* choice_ppshader;
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ struct VertexShaderConstants
|
||||||
float4 normalmatrices[32];
|
float4 normalmatrices[32];
|
||||||
float4 posttransformmatrices[64];
|
float4 posttransformmatrices[64];
|
||||||
float4 pixelcentercorrection;
|
float4 pixelcentercorrection;
|
||||||
|
float4 viewport;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GeometryShaderConstants
|
struct GeometryShaderConstants
|
||||||
|
|
|
@ -275,6 +275,7 @@ inline const char* GetInterpolationQualifier(bool msaa, bool ssaa,
|
||||||
#define I_NORMALMATRICES "cnmtx"
|
#define I_NORMALMATRICES "cnmtx"
|
||||||
#define I_POSTTRANSFORMMATRICES "cpostmtx"
|
#define I_POSTTRANSFORMMATRICES "cpostmtx"
|
||||||
#define I_PIXELCENTERCORRECTION "cpixelcenter"
|
#define I_PIXELCENTERCORRECTION "cpixelcenter"
|
||||||
|
#define I_VIEWPORT_SIZE "cviewport"
|
||||||
|
|
||||||
#define I_STEREOPARAMS "cstereo"
|
#define I_STEREOPARAMS "cstereo"
|
||||||
#define I_LINEPTPARAMS "clinept"
|
#define I_LINEPTPARAMS "clinept"
|
||||||
|
@ -288,4 +289,5 @@ static const char s_shader_uniforms[] = "\tfloat4 " I_POSNORMALMATRIX "[6];\n"
|
||||||
"\tfloat4 " I_TRANSFORMMATRICES "[64];\n"
|
"\tfloat4 " I_TRANSFORMMATRICES "[64];\n"
|
||||||
"\tfloat4 " I_NORMALMATRICES "[32];\n"
|
"\tfloat4 " I_NORMALMATRICES "[32];\n"
|
||||||
"\tfloat4 " I_POSTTRANSFORMMATRICES "[64];\n"
|
"\tfloat4 " I_POSTTRANSFORMMATRICES "[64];\n"
|
||||||
"\tfloat4 " I_PIXELCENTERCORRECTION ";\n";
|
"\tfloat4 " I_PIXELCENTERCORRECTION ";\n"
|
||||||
|
"\tfloat2 " I_VIEWPORT_SIZE ";\n";
|
||||||
|
|
|
@ -28,6 +28,8 @@ VertexShaderUid GetVertexShaderUid()
|
||||||
uid_data->numTexGens = xfmem.numTexGen.numTexGens;
|
uid_data->numTexGens = xfmem.numTexGen.numTexGens;
|
||||||
uid_data->components = VertexLoaderManager::g_current_components;
|
uid_data->components = VertexLoaderManager::g_current_components;
|
||||||
uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
|
uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
|
||||||
|
uid_data->vertex_rounding =
|
||||||
|
g_ActiveConfig.bVertexRounding && g_ActiveConfig.iEFBScale != SCALE_1X;
|
||||||
uid_data->msaa = g_ActiveConfig.iMultisamples > 1;
|
uid_data->msaa = g_ActiveConfig.iMultisamples > 1;
|
||||||
uid_data->ssaa = g_ActiveConfig.iMultisamples > 1 && g_ActiveConfig.bSSAA;
|
uid_data->ssaa = g_ActiveConfig.iMultisamples > 1 && g_ActiveConfig.bSSAA;
|
||||||
uid_data->numColorChans = xfmem.numChan.numColorChans;
|
uid_data->numColorChans = xfmem.numChan.numColorChans;
|
||||||
|
@ -465,6 +467,29 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const vertex_shader_uid_da
|
||||||
// get rasterized correctly.
|
// get rasterized correctly.
|
||||||
out.Write("o.pos.xy = o.pos.xy - o.pos.w * " I_PIXELCENTERCORRECTION ".xy;\n");
|
out.Write("o.pos.xy = o.pos.xy - o.pos.w * " I_PIXELCENTERCORRECTION ".xy;\n");
|
||||||
|
|
||||||
|
if (uid_data->vertex_rounding)
|
||||||
|
{
|
||||||
|
// By now our position is in clip space
|
||||||
|
// however, higher resolutions than the Wii outputs
|
||||||
|
// cause an additional pixel offset
|
||||||
|
// due to a higher pixel density
|
||||||
|
// we need to correct this by converting our
|
||||||
|
// clip-space position into the Wii's screen-space
|
||||||
|
// acquire the right pixel and then convert it back
|
||||||
|
out.Write("if (o.pos.w == 1.0f)\n");
|
||||||
|
out.Write("{\n");
|
||||||
|
|
||||||
|
out.Write("\tfloat ss_pixel_x = ((o.pos.x + 1.0f) * (" I_VIEWPORT_SIZE ".x * 0.5f));\n");
|
||||||
|
out.Write("\tfloat ss_pixel_y = ((o.pos.y + 1.0f) * (" I_VIEWPORT_SIZE ".y * 0.5f));\n");
|
||||||
|
|
||||||
|
out.Write("\tss_pixel_x = round(ss_pixel_x);\n");
|
||||||
|
out.Write("\tss_pixel_y = round(ss_pixel_y);\n");
|
||||||
|
|
||||||
|
out.Write("\to.pos.x = ((ss_pixel_x / (" I_VIEWPORT_SIZE ".x * 0.5f)) - 1.0f);\n");
|
||||||
|
out.Write("\to.pos.y = ((ss_pixel_y / (" I_VIEWPORT_SIZE ".y * 0.5f)) - 1.0f);\n");
|
||||||
|
out.Write("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
|
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders || api_type == APIType::Vulkan)
|
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders || api_type == APIType::Vulkan)
|
||||||
|
|
|
@ -43,7 +43,8 @@ struct vertex_shader_uid_data
|
||||||
u32 texMtxInfo_n_projection : 16; // Stored separately to guarantee that the texMtxInfo struct is
|
u32 texMtxInfo_n_projection : 16; // Stored separately to guarantee that the texMtxInfo struct is
|
||||||
// 8 bits wide
|
// 8 bits wide
|
||||||
u32 ssaa : 1;
|
u32 ssaa : 1;
|
||||||
u32 pad : 15;
|
u32 vertex_rounding : 1;
|
||||||
|
u32 pad : 14;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -382,8 +382,16 @@ void VertexShaderManager::SetConstants()
|
||||||
// NOTE: If we ever emulate antialiasing, the sample locations set by
|
// NOTE: If we ever emulate antialiasing, the sample locations set by
|
||||||
// BP registers 0x01-0x04 need to be considered here.
|
// BP registers 0x01-0x04 need to be considered here.
|
||||||
const float pixel_center_correction = 7.0f / 12.0f - 0.5f;
|
const float pixel_center_correction = 7.0f / 12.0f - 0.5f;
|
||||||
const float pixel_size_x = 2.f / g_renderer->EFBToScaledXf(2.f * xfmem.viewport.wd);
|
const bool bUseVertexRounding =
|
||||||
const float pixel_size_y = 2.f / g_renderer->EFBToScaledXf(2.f * xfmem.viewport.ht);
|
g_ActiveConfig.bVertexRounding && g_ActiveConfig.iEFBScale != SCALE_1X;
|
||||||
|
const float viewport_width = bUseVertexRounding ?
|
||||||
|
(2.f * xfmem.viewport.wd) :
|
||||||
|
g_renderer->EFBToScaledXf(2.f * xfmem.viewport.wd);
|
||||||
|
const float viewport_height = bUseVertexRounding ?
|
||||||
|
(2.f * xfmem.viewport.ht) :
|
||||||
|
g_renderer->EFBToScaledXf(2.f * xfmem.viewport.ht);
|
||||||
|
const float pixel_size_x = 2.f / viewport_width;
|
||||||
|
const float pixel_size_y = 2.f / viewport_height;
|
||||||
constants.pixelcentercorrection[0] = pixel_center_correction * pixel_size_x;
|
constants.pixelcentercorrection[0] = pixel_center_correction * pixel_size_x;
|
||||||
constants.pixelcentercorrection[1] = pixel_center_correction * pixel_size_y;
|
constants.pixelcentercorrection[1] = pixel_center_correction * pixel_size_y;
|
||||||
|
|
||||||
|
@ -391,6 +399,9 @@ void VertexShaderManager::SetConstants()
|
||||||
constants.pixelcentercorrection[2] = 1.0f;
|
constants.pixelcentercorrection[2] = 1.0f;
|
||||||
constants.pixelcentercorrection[3] = 0.0f;
|
constants.pixelcentercorrection[3] = 0.0f;
|
||||||
|
|
||||||
|
constants.viewport[0] = (2.f * xfmem.viewport.wd);
|
||||||
|
constants.viewport[1] = (2.f * xfmem.viewport.ht);
|
||||||
|
|
||||||
if (g_renderer->UseVertexDepthRange())
|
if (g_renderer->UseVertexDepthRange())
|
||||||
{
|
{
|
||||||
// Oversized depth ranges are handled in the vertex shader. We need to reverse
|
// Oversized depth ranges are handled in the vertex shader. We need to reverse
|
||||||
|
|
|
@ -125,6 +125,7 @@ void VideoConfig::Load(const std::string& ini_file)
|
||||||
hacks->Get("EFBToTextureEnable", &bSkipEFBCopyToRam, true);
|
hacks->Get("EFBToTextureEnable", &bSkipEFBCopyToRam, true);
|
||||||
hacks->Get("EFBScaledCopy", &bCopyEFBScaled, true);
|
hacks->Get("EFBScaledCopy", &bCopyEFBScaled, true);
|
||||||
hacks->Get("EFBEmulateFormatChanges", &bEFBEmulateFormatChanges, false);
|
hacks->Get("EFBEmulateFormatChanges", &bEFBEmulateFormatChanges, false);
|
||||||
|
hacks->Get("VertexRounding", &bVertexRounding, false);
|
||||||
|
|
||||||
// hacks which are disabled by default
|
// hacks which are disabled by default
|
||||||
iPhackvalue[0] = 0;
|
iPhackvalue[0] = 0;
|
||||||
|
@ -228,6 +229,7 @@ void VideoConfig::GameIniLoad()
|
||||||
CHECK_SETTING("Video_Hacks", "EFBToTextureEnable", bSkipEFBCopyToRam);
|
CHECK_SETTING("Video_Hacks", "EFBToTextureEnable", bSkipEFBCopyToRam);
|
||||||
CHECK_SETTING("Video_Hacks", "EFBScaledCopy", bCopyEFBScaled);
|
CHECK_SETTING("Video_Hacks", "EFBScaledCopy", bCopyEFBScaled);
|
||||||
CHECK_SETTING("Video_Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges);
|
CHECK_SETTING("Video_Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges);
|
||||||
|
CHECK_SETTING("Video_Hacks", "VertexRounding", bVertexRounding);
|
||||||
|
|
||||||
CHECK_SETTING("Video", "ProjectionHack", iPhackvalue[0]);
|
CHECK_SETTING("Video", "ProjectionHack", iPhackvalue[0]);
|
||||||
CHECK_SETTING("Video", "PH_SZNear", iPhackvalue[1]);
|
CHECK_SETTING("Video", "PH_SZNear", iPhackvalue[1]);
|
||||||
|
@ -350,6 +352,7 @@ void VideoConfig::Save(const std::string& ini_file)
|
||||||
hacks->Set("EFBToTextureEnable", bSkipEFBCopyToRam);
|
hacks->Set("EFBToTextureEnable", bSkipEFBCopyToRam);
|
||||||
hacks->Set("EFBScaledCopy", bCopyEFBScaled);
|
hacks->Set("EFBScaledCopy", bCopyEFBScaled);
|
||||||
hacks->Set("EFBEmulateFormatChanges", bEFBEmulateFormatChanges);
|
hacks->Set("EFBEmulateFormatChanges", bEFBEmulateFormatChanges);
|
||||||
|
hacks->Set("VertexRounding", bVertexRounding);
|
||||||
|
|
||||||
iniFile.Save(ini_file);
|
iniFile.Save(ini_file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,7 @@ struct VideoConfig final
|
||||||
float fAspectRatioHackW, fAspectRatioHackH;
|
float fAspectRatioHackW, fAspectRatioHackH;
|
||||||
bool bEnablePixelLighting;
|
bool bEnablePixelLighting;
|
||||||
bool bFastDepthCalc;
|
bool bFastDepthCalc;
|
||||||
|
bool bVertexRounding;
|
||||||
int iLog; // CONF_ bits
|
int iLog; // CONF_ bits
|
||||||
int iSaveTargetId; // TODO: Should be dropped
|
int iSaveTargetId; // TODO: Should be dropped
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue