mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 15:45:42 +00:00
GPU/HW: Add 'Force Round Upscaled Texture Coordinates'
This commit is contained in:
parent
1582b2ae5d
commit
8455c9c3c6
|
@ -4142,6 +4142,7 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
||||||
|
|
||||||
SettingsInterface* bsi = GetEditingSettingsInterface();
|
SettingsInterface* bsi = GetEditingSettingsInterface();
|
||||||
const bool game_settings = IsEditingGameSettings(bsi);
|
const bool game_settings = IsEditingGameSettings(bsi);
|
||||||
|
const u32 resolution_scale = GetEffectiveUIntSetting(bsi, "GPU", "ResolutionScale", 1);
|
||||||
|
|
||||||
BeginMenuButtons();
|
BeginMenuButtons();
|
||||||
|
|
||||||
|
@ -4298,43 +4299,46 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
||||||
"GPU", "UseSoftwareRendererForReadbacks", false);
|
"GPU", "UseSoftwareRendererForReadbacks", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuHeading(FSUI_CSTR("Rendering"));
|
if (is_hardware)
|
||||||
|
{
|
||||||
|
MenuHeading(FSUI_CSTR("Rendering"));
|
||||||
|
|
||||||
DrawIntListSetting(
|
DrawIntListSetting(
|
||||||
bsi, FSUI_CSTR("Internal Resolution"),
|
bsi, FSUI_CSTR("Internal Resolution"),
|
||||||
FSUI_CSTR("Scales internal VRAM resolution by the specified multiplier. Some games require 1x VRAM resolution."),
|
FSUI_CSTR("Scales internal VRAM resolution by the specified multiplier. Some games require 1x VRAM resolution."),
|
||||||
"GPU", "ResolutionScale", 1, resolution_scales.data(), resolution_scales.size(), true, 0, is_hardware);
|
"GPU", "ResolutionScale", 1, resolution_scales.data(), resolution_scales.size(), true, 0);
|
||||||
|
|
||||||
DrawEnumSetting(
|
DrawEnumSetting(bsi, FSUI_CSTR("Texture Filtering"),
|
||||||
bsi, FSUI_CSTR("Texture Filtering"), FSUI_CSTR("Smooths out the blockiness of magnified textures on 3D objects."),
|
FSUI_CSTR("Smooths out the blockiness of magnified textures on 3D objects."), "GPU",
|
||||||
"GPU", "TextureFilter", Settings::DEFAULT_GPU_TEXTURE_FILTER, &Settings::ParseTextureFilterName,
|
"TextureFilter", Settings::DEFAULT_GPU_TEXTURE_FILTER, &Settings::ParseTextureFilterName,
|
||||||
&Settings::GetTextureFilterName, &Settings::GetTextureFilterDisplayName, GPUTextureFilter::Count, is_hardware);
|
&Settings::GetTextureFilterName, &Settings::GetTextureFilterDisplayName, GPUTextureFilter::Count);
|
||||||
|
|
||||||
DrawEnumSetting(bsi, FSUI_CSTR("Line Detection"),
|
DrawEnumSetting(bsi, FSUI_CSTR("Line Detection"),
|
||||||
FSUI_CSTR("Attempts to detect one pixel high/wide lines that rely on non-upscaled rasterization "
|
FSUI_CSTR("Attempts to detect one pixel high/wide lines that rely on non-upscaled rasterization "
|
||||||
"behavior, filling in gaps introduced by upscaling."),
|
"behavior, filling in gaps introduced by upscaling."),
|
||||||
"GPU", "LineDetectMode", Settings::DEFAULT_GPU_LINE_DETECT_MODE, &Settings::ParseLineDetectModeName,
|
"GPU", "LineDetectMode", Settings::DEFAULT_GPU_LINE_DETECT_MODE, &Settings::ParseLineDetectModeName,
|
||||||
&Settings::GetLineDetectModeName, &Settings::GetLineDetectModeDisplayName, GPULineDetectMode::Count,
|
&Settings::GetLineDetectModeName, &Settings::GetLineDetectModeDisplayName, GPULineDetectMode::Count,
|
||||||
is_hardware);
|
resolution_scale > 1);
|
||||||
|
|
||||||
DrawToggleSetting(bsi, FSUI_CSTR("True Color Rendering"),
|
DrawToggleSetting(bsi, FSUI_CSTR("True Color Rendering"),
|
||||||
FSUI_CSTR("Disables dithering and uses the full 8 bits per channel of color information."), "GPU",
|
FSUI_CSTR("Disables dithering and uses the full 8 bits per channel of color information."), "GPU",
|
||||||
"TrueColor", true, is_hardware);
|
"TrueColor", true);
|
||||||
|
|
||||||
DrawToggleSetting(
|
DrawToggleSetting(
|
||||||
bsi, FSUI_CSTR("True Color Debanding"),
|
bsi, FSUI_CSTR("True Color Debanding"),
|
||||||
FSUI_CSTR("Applies modern dithering techniques to further smooth out gradients when true color is enabled."), "GPU",
|
FSUI_CSTR("Applies modern dithering techniques to further smooth out gradients when true color is enabled."),
|
||||||
"Debanding", false, is_hardware && bsi->GetBoolValue("GPU", "TrueColor", false));
|
"GPU", "Debanding", false, bsi->GetBoolValue("GPU", "TrueColor", false));
|
||||||
|
|
||||||
DrawToggleSetting(bsi, FSUI_CSTR("Widescreen Hack"),
|
DrawToggleSetting(bsi, FSUI_CSTR("Widescreen Hack"),
|
||||||
FSUI_CSTR("Increases the field of view from 4:3 to the chosen display aspect ratio in 3D games."),
|
FSUI_CSTR("Increases the field of view from 4:3 to the chosen display aspect ratio in 3D games."),
|
||||||
"GPU", "WidescreenHack", false, is_hardware);
|
"GPU", "WidescreenHack", false);
|
||||||
|
|
||||||
DrawToggleSetting(
|
DrawToggleSetting(
|
||||||
bsi, FSUI_CSTR("PGXP Geometry Correction"),
|
bsi, FSUI_CSTR("PGXP Geometry Correction"),
|
||||||
FSUI_CSTR("Reduces \"wobbly\" polygons by attempting to preserve the fractional component through memory "
|
FSUI_CSTR("Reduces \"wobbly\" polygons by attempting to preserve the fractional component through memory "
|
||||||
"transfers."),
|
"transfers."),
|
||||||
"GPU", "PGXPEnable", false);
|
"GPU", "PGXPEnable", false);
|
||||||
|
}
|
||||||
|
|
||||||
MenuHeading(FSUI_CSTR("Screen Display"));
|
MenuHeading(FSUI_CSTR("Screen Display"));
|
||||||
|
|
||||||
|
@ -4401,12 +4405,6 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
||||||
"ScreenshotQuality", Settings::DEFAULT_DISPLAY_SCREENSHOT_QUALITY, 1, 100, "%d%%");
|
"ScreenshotQuality", Settings::DEFAULT_DISPLAY_SCREENSHOT_QUALITY, 1, 100, "%d%%");
|
||||||
|
|
||||||
MenuHeading(FSUI_CSTR("Enhancements"));
|
MenuHeading(FSUI_CSTR("Enhancements"));
|
||||||
DrawToggleSetting(
|
|
||||||
bsi, FSUI_CSTR("Scaled Dithering"),
|
|
||||||
FSUI_CSTR("Scales the dithering pattern with the internal rendering resolution, making it less noticeable. "
|
|
||||||
"Usually safe to enable."),
|
|
||||||
"GPU", "ScaledDithering", true, is_hardware);
|
|
||||||
|
|
||||||
DrawToggleSetting(
|
DrawToggleSetting(
|
||||||
bsi, FSUI_CSTR("Disable Interlacing"),
|
bsi, FSUI_CSTR("Disable Interlacing"),
|
||||||
FSUI_CSTR("Disables interlaced rendering and display in the GPU. Some games can render in 480p this way, "
|
FSUI_CSTR("Disables interlaced rendering and display in the GPU. Some games can render in 480p this way, "
|
||||||
|
@ -4421,46 +4419,67 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
||||||
bsi, FSUI_CSTR("Force 4:3 For 24-Bit Display"),
|
bsi, FSUI_CSTR("Force 4:3 For 24-Bit Display"),
|
||||||
FSUI_CSTR("Switches back to 4:3 display aspect ratio when displaying 24-bit content, usually FMVs."), "Display",
|
FSUI_CSTR("Switches back to 4:3 display aspect ratio when displaying 24-bit content, usually FMVs."), "Display",
|
||||||
"Force4_3For24Bit", false);
|
"Force4_3For24Bit", false);
|
||||||
DrawToggleSetting(bsi, FSUI_CSTR("Chroma Smoothing For 24-Bit Display"),
|
|
||||||
FSUI_CSTR("Smooths out blockyness between colour transitions in 24-bit content, usually FMVs. Only "
|
|
||||||
"applies to the hardware renderers."),
|
|
||||||
"GPU", "ChromaSmoothing24Bit", false);
|
|
||||||
|
|
||||||
MenuHeading(FSUI_CSTR("PGXP (Precision Geometry Transform Pipeline)"));
|
if (is_hardware)
|
||||||
|
{
|
||||||
|
const GPUTextureFilter texture_filtering =
|
||||||
|
Settings::ParseTextureFilterName(
|
||||||
|
GetEffectiveTinyStringSetting(bsi, "GPU", "TextureFilter",
|
||||||
|
Settings::GetTextureFilterName(Settings::DEFAULT_GPU_TEXTURE_FILTER)))
|
||||||
|
.value_or(Settings::DEFAULT_GPU_TEXTURE_FILTER);
|
||||||
|
|
||||||
const bool pgxp_enabled = GetEffectiveBoolSetting(bsi, "GPU", "PGXPEnable", false);
|
DrawToggleSetting(
|
||||||
const bool texture_correction_enabled = GetEffectiveBoolSetting(bsi, "GPU", "PGXPTextureCorrection", true);
|
bsi, FSUI_CSTR("Scaled Dithering"),
|
||||||
|
FSUI_CSTR("Scales the dithering pattern with the internal rendering resolution, making it less noticeable. "
|
||||||
|
"Usually safe to enable."),
|
||||||
|
"GPU", "ScaledDithering", true, resolution_scale > 1);
|
||||||
|
DrawToggleSetting(bsi, FSUI_CSTR("Chroma Smoothing For 24-Bit Display"),
|
||||||
|
FSUI_CSTR("Smooths out blockyness between colour transitions in 24-bit content, usually FMVs."),
|
||||||
|
"GPU", "ChromaSmoothing24Bit", false);
|
||||||
|
DrawToggleSetting(
|
||||||
|
bsi, FSUI_CSTR("Round Upscaled Texture Coordinates"),
|
||||||
|
FSUI_CSTR("Rounds texture coordinates instead of flooring when upscaling. Can fix misaligned "
|
||||||
|
"textures in some games, but break others, and is incompatible with texture filtering."),
|
||||||
|
"GPU", "ForceRoundTextureCoordinates", false,
|
||||||
|
resolution_scale > 1 && texture_filtering == GPUTextureFilter::Nearest);
|
||||||
|
|
||||||
DrawToggleSetting(
|
MenuHeading(FSUI_CSTR("PGXP (Precision Geometry Transform Pipeline)"));
|
||||||
bsi, FSUI_CSTR("Perspective Correct Textures"),
|
|
||||||
FSUI_CSTR("Uses perspective-correct interpolation for texture coordinates, straightening out warped textures."),
|
|
||||||
"GPU", "PGXPTextureCorrection", true, pgxp_enabled);
|
|
||||||
DrawToggleSetting(
|
|
||||||
bsi, FSUI_CSTR("Perspective Correct Colors"),
|
|
||||||
FSUI_CSTR("Uses perspective-correct interpolation for colors, which can improve visuals in some games."), "GPU",
|
|
||||||
"PGXPColorCorrection", false, pgxp_enabled);
|
|
||||||
DrawToggleSetting(bsi, FSUI_CSTR("Culling Correction"),
|
|
||||||
FSUI_CSTR("Increases the precision of polygon culling, reducing the number of holes in geometry."),
|
|
||||||
"GPU", "PGXPCulling", true, pgxp_enabled);
|
|
||||||
DrawToggleSetting(
|
|
||||||
bsi, FSUI_CSTR("Preserve Projection Precision"),
|
|
||||||
FSUI_CSTR("Adds additional precision to PGXP data post-projection. May improve visuals in some games."), "GPU",
|
|
||||||
"PGXPPreserveProjFP", false, pgxp_enabled);
|
|
||||||
DrawToggleSetting(bsi, FSUI_CSTR("Depth Buffer"),
|
|
||||||
FSUI_CSTR("Reduces polygon Z-fighting through depth testing. Low compatibility with games."), "GPU",
|
|
||||||
"PGXPDepthBuffer", false, pgxp_enabled && texture_correction_enabled);
|
|
||||||
DrawToggleSetting(bsi, FSUI_CSTR("CPU Mode"),
|
|
||||||
FSUI_CSTR("Uses PGXP for all instructions, not just memory operations."), "GPU", "PGXPCPU", false,
|
|
||||||
pgxp_enabled);
|
|
||||||
|
|
||||||
MenuHeading(FSUI_CSTR("Texture Replacements"));
|
const bool pgxp_enabled = GetEffectiveBoolSetting(bsi, "GPU", "PGXPEnable", false);
|
||||||
|
const bool texture_correction_enabled = GetEffectiveBoolSetting(bsi, "GPU", "PGXPTextureCorrection", true);
|
||||||
|
|
||||||
DrawToggleSetting(bsi, FSUI_CSTR("Enable VRAM Write Texture Replacement"),
|
DrawToggleSetting(
|
||||||
FSUI_CSTR("Enables the replacement of background textures in supported games."),
|
bsi, FSUI_CSTR("Perspective Correct Textures"),
|
||||||
"TextureReplacements", "EnableVRAMWriteReplacements", false);
|
FSUI_CSTR("Uses perspective-correct interpolation for texture coordinates, straightening out warped textures."),
|
||||||
DrawToggleSetting(bsi, FSUI_CSTR("Preload Replacement Textures"),
|
"GPU", "PGXPTextureCorrection", true, pgxp_enabled);
|
||||||
FSUI_CSTR("Loads all replacement texture to RAM, reducing stuttering at runtime."),
|
DrawToggleSetting(
|
||||||
"TextureReplacements", "PreloadTextures", false);
|
bsi, FSUI_CSTR("Perspective Correct Colors"),
|
||||||
|
FSUI_CSTR("Uses perspective-correct interpolation for colors, which can improve visuals in some games."), "GPU",
|
||||||
|
"PGXPColorCorrection", false, pgxp_enabled);
|
||||||
|
DrawToggleSetting(
|
||||||
|
bsi, FSUI_CSTR("Culling Correction"),
|
||||||
|
FSUI_CSTR("Increases the precision of polygon culling, reducing the number of holes in geometry."), "GPU",
|
||||||
|
"PGXPCulling", true, pgxp_enabled);
|
||||||
|
DrawToggleSetting(
|
||||||
|
bsi, FSUI_CSTR("Preserve Projection Precision"),
|
||||||
|
FSUI_CSTR("Adds additional precision to PGXP data post-projection. May improve visuals in some games."), "GPU",
|
||||||
|
"PGXPPreserveProjFP", false, pgxp_enabled);
|
||||||
|
DrawToggleSetting(bsi, FSUI_CSTR("Depth Buffer"),
|
||||||
|
FSUI_CSTR("Reduces polygon Z-fighting through depth testing. Low compatibility with games."),
|
||||||
|
"GPU", "PGXPDepthBuffer", false, pgxp_enabled && texture_correction_enabled);
|
||||||
|
DrawToggleSetting(bsi, FSUI_CSTR("CPU Mode"),
|
||||||
|
FSUI_CSTR("Uses PGXP for all instructions, not just memory operations."), "GPU", "PGXPCPU", false,
|
||||||
|
pgxp_enabled);
|
||||||
|
|
||||||
|
MenuHeading(FSUI_CSTR("Texture Replacements"));
|
||||||
|
|
||||||
|
DrawToggleSetting(bsi, FSUI_CSTR("Enable VRAM Write Texture Replacement"),
|
||||||
|
FSUI_CSTR("Enables the replacement of background textures in supported games."),
|
||||||
|
"TextureReplacements", "EnableVRAMWriteReplacements", false);
|
||||||
|
DrawToggleSetting(bsi, FSUI_CSTR("Preload Replacement Textures"),
|
||||||
|
FSUI_CSTR("Loads all replacement texture to RAM, reducing stuttering at runtime."),
|
||||||
|
"TextureReplacements", "PreloadTextures", false);
|
||||||
|
}
|
||||||
|
|
||||||
EndMenuButtons();
|
EndMenuButtons();
|
||||||
}
|
}
|
||||||
|
@ -7591,6 +7610,8 @@ TRANSLATE_NOOP("FullscreenUI", "Rewind for {0} frames, lasting {1:.2f} seconds w
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Rewind is disabled because runahead is enabled. Runahead will significantly increase system requirements.");
|
TRANSLATE_NOOP("FullscreenUI", "Rewind is disabled because runahead is enabled. Runahead will significantly increase system requirements.");
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Rewind is not enabled. Please note that enabling rewind may significantly increase system requirements.");
|
TRANSLATE_NOOP("FullscreenUI", "Rewind is not enabled. Please note that enabling rewind may significantly increase system requirements.");
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Rich presence inactive or unsupported.");
|
TRANSLATE_NOOP("FullscreenUI", "Rich presence inactive or unsupported.");
|
||||||
|
TRANSLATE_NOOP("FullscreenUI", "Round Upscaled Texture Coordinates");
|
||||||
|
TRANSLATE_NOOP("FullscreenUI", "Rounds texture coordinates instead of flooring when upscaling. Can fix misaligned textures in some games, but break others.");
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Runahead");
|
TRANSLATE_NOOP("FullscreenUI", "Runahead");
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Runahead/Rewind");
|
TRANSLATE_NOOP("FullscreenUI", "Runahead/Rewind");
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Runs the software renderer in parallel for VRAM readbacks. On some systems, this may result in greater performance.");
|
TRANSLATE_NOOP("FullscreenUI", "Runs the software renderer in parallel for VRAM readbacks. On some systems, this may result in greater performance.");
|
||||||
|
@ -7675,7 +7696,7 @@ TRANSLATE_NOOP("FullscreenUI", "Simulates the system ahead of time and rolls bac
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Skip Duplicate Frame Display");
|
TRANSLATE_NOOP("FullscreenUI", "Skip Duplicate Frame Display");
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Skips the presentation/display of frames that are not unique. Can result in worse frame pacing.");
|
TRANSLATE_NOOP("FullscreenUI", "Skips the presentation/display of frames that are not unique. Can result in worse frame pacing.");
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Slow Boot");
|
TRANSLATE_NOOP("FullscreenUI", "Slow Boot");
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Smooths out blockyness between colour transitions in 24-bit content, usually FMVs. Only applies to the hardware renderers.");
|
TRANSLATE_NOOP("FullscreenUI", "Smooths out blockyness between colour transitions in 24-bit content, usually FMVs.");
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Smooths out the blockiness of magnified textures on 3D objects.");
|
TRANSLATE_NOOP("FullscreenUI", "Smooths out the blockiness of magnified textures on 3D objects.");
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Sort By");
|
TRANSLATE_NOOP("FullscreenUI", "Sort By");
|
||||||
TRANSLATE_NOOP("FullscreenUI", "Sort Reversed");
|
TRANSLATE_NOOP("FullscreenUI", "Sort Reversed");
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace GameDatabase {
|
||||||
enum : u32
|
enum : u32
|
||||||
{
|
{
|
||||||
GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48,
|
GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48,
|
||||||
GAME_DATABASE_CACHE_VERSION = 8,
|
GAME_DATABASE_CACHE_VERSION = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Entry* GetMutableEntry(std::string_view serial);
|
static Entry* GetMutableEntry(std::string_view serial);
|
||||||
|
@ -63,6 +63,7 @@ static constexpr const std::array<const char*, static_cast<u32>(GameDatabase::Tr
|
||||||
"ForceInterpreter",
|
"ForceInterpreter",
|
||||||
"ForceSoftwareRenderer",
|
"ForceSoftwareRenderer",
|
||||||
"ForceSoftwareRendererForReadbacks",
|
"ForceSoftwareRendererForReadbacks",
|
||||||
|
"ForceRoundTextureCoordinates",
|
||||||
"ForceInterlacing",
|
"ForceInterlacing",
|
||||||
"DisableTrueColor",
|
"DisableTrueColor",
|
||||||
"DisableUpscaling",
|
"DisableUpscaling",
|
||||||
|
@ -88,6 +89,7 @@ static constexpr const std::array<const char*, static_cast<u32>(GameDatabase::Tr
|
||||||
TRANSLATE_NOOP("GameDatabase", "Force Interpreter"),
|
TRANSLATE_NOOP("GameDatabase", "Force Interpreter"),
|
||||||
TRANSLATE_NOOP("GameDatabase", "Force Software Renderer"),
|
TRANSLATE_NOOP("GameDatabase", "Force Software Renderer"),
|
||||||
TRANSLATE_NOOP("GameDatabase", "Force Software Renderer For Readbacks"),
|
TRANSLATE_NOOP("GameDatabase", "Force Software Renderer For Readbacks"),
|
||||||
|
TRANSLATE_NOOP("GameDatabase", "Force Round Texture Coordinates"),
|
||||||
TRANSLATE_NOOP("GameDatabase", "Force Interlacing"),
|
TRANSLATE_NOOP("GameDatabase", "Force Interlacing"),
|
||||||
TRANSLATE_NOOP("GameDatabase", "Disable True Color"),
|
TRANSLATE_NOOP("GameDatabase", "Disable True Color"),
|
||||||
TRANSLATE_NOOP("GameDatabase", "Disable Upscaling"),
|
TRANSLATE_NOOP("GameDatabase", "Disable Upscaling"),
|
||||||
|
@ -434,6 +436,11 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
|
||||||
settings.gpu_use_software_renderer_for_readbacks = true;
|
settings.gpu_use_software_renderer_for_readbacks = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HasTrait(Trait::ForceRoundUpscaledTextureCoordinates))
|
||||||
|
{
|
||||||
|
settings.gpu_force_round_texcoords = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (HasTrait(Trait::ForceInterlacing))
|
if (HasTrait(Trait::ForceInterlacing))
|
||||||
{
|
{
|
||||||
if (display_osd_messages && settings.gpu_disable_interlacing)
|
if (display_osd_messages && settings.gpu_disable_interlacing)
|
||||||
|
|
|
@ -31,6 +31,7 @@ enum class Trait : u32
|
||||||
ForceInterpreter,
|
ForceInterpreter,
|
||||||
ForceSoftwareRenderer,
|
ForceSoftwareRenderer,
|
||||||
ForceSoftwareRendererForReadbacks,
|
ForceSoftwareRendererForReadbacks,
|
||||||
|
ForceRoundUpscaledTextureCoordinates,
|
||||||
ForceInterlacing,
|
ForceInterlacing,
|
||||||
DisableTrueColor,
|
DisableTrueColor,
|
||||||
DisableUpscaling,
|
DisableUpscaling,
|
||||||
|
|
|
@ -198,7 +198,9 @@ bool GPU_HW::Initialize()
|
||||||
m_per_sample_shading = g_settings.gpu_per_sample_shading && features.per_sample_shading;
|
m_per_sample_shading = g_settings.gpu_per_sample_shading && features.per_sample_shading;
|
||||||
m_true_color = g_settings.gpu_true_color;
|
m_true_color = g_settings.gpu_true_color;
|
||||||
m_debanding = g_settings.gpu_debanding;
|
m_debanding = g_settings.gpu_debanding;
|
||||||
m_scaled_dithering = g_settings.gpu_scaled_dithering;
|
m_scaled_dithering = (m_resolution_scale > 1 && g_settings.gpu_scaled_dithering);
|
||||||
|
m_force_round_texcoords = (m_resolution_scale > 1 && g_settings.gpu_force_round_texcoords &&
|
||||||
|
g_settings.gpu_texture_filter == GPUTextureFilter::Nearest);
|
||||||
m_texture_filtering = g_settings.gpu_texture_filter;
|
m_texture_filtering = g_settings.gpu_texture_filter;
|
||||||
m_line_detect_mode = (m_resolution_scale > 1) ? g_settings.gpu_line_detect_mode : GPULineDetectMode::Disabled;
|
m_line_detect_mode = (m_resolution_scale > 1) ? g_settings.gpu_line_detect_mode : GPULineDetectMode::Disabled;
|
||||||
m_clamp_uvs = ShouldClampUVs();
|
m_clamp_uvs = ShouldClampUVs();
|
||||||
|
@ -336,7 +338,10 @@ void GPU_HW::UpdateSettings(const Settings& old_settings)
|
||||||
const bool shaders_changed =
|
const bool shaders_changed =
|
||||||
(m_resolution_scale != resolution_scale || m_multisamples != multisamples ||
|
(m_resolution_scale != resolution_scale || m_multisamples != multisamples ||
|
||||||
m_true_color != g_settings.gpu_true_color || m_debanding != g_settings.gpu_debanding ||
|
m_true_color != g_settings.gpu_true_color || m_debanding != g_settings.gpu_debanding ||
|
||||||
m_per_sample_shading != per_sample_shading || m_scaled_dithering != g_settings.gpu_scaled_dithering ||
|
m_per_sample_shading != per_sample_shading ||
|
||||||
|
m_scaled_dithering != (resolution_scale > 1 && g_settings.gpu_scaled_dithering) ||
|
||||||
|
m_force_round_texcoords != (resolution_scale > 1 && g_settings.gpu_force_round_texcoords &&
|
||||||
|
g_settings.gpu_texture_filter == GPUTextureFilter::Nearest) ||
|
||||||
m_texture_filtering != g_settings.gpu_texture_filter || m_clamp_uvs != clamp_uvs ||
|
m_texture_filtering != g_settings.gpu_texture_filter || m_clamp_uvs != clamp_uvs ||
|
||||||
m_downsample_mode != downsample_mode ||
|
m_downsample_mode != downsample_mode ||
|
||||||
(m_downsample_mode == GPUDownsampleMode::Box &&
|
(m_downsample_mode == GPUDownsampleMode::Box &&
|
||||||
|
@ -386,7 +391,9 @@ void GPU_HW::UpdateSettings(const Settings& old_settings)
|
||||||
m_per_sample_shading = per_sample_shading;
|
m_per_sample_shading = per_sample_shading;
|
||||||
m_true_color = g_settings.gpu_true_color;
|
m_true_color = g_settings.gpu_true_color;
|
||||||
m_debanding = g_settings.gpu_debanding;
|
m_debanding = g_settings.gpu_debanding;
|
||||||
m_scaled_dithering = g_settings.gpu_scaled_dithering;
|
m_scaled_dithering = (m_resolution_scale > 1 && g_settings.gpu_scaled_dithering);
|
||||||
|
m_force_round_texcoords = (m_resolution_scale > 1 && g_settings.gpu_force_round_texcoords &&
|
||||||
|
g_settings.gpu_texture_filter == GPUTextureFilter::Nearest);
|
||||||
m_texture_filtering = g_settings.gpu_texture_filter;
|
m_texture_filtering = g_settings.gpu_texture_filter;
|
||||||
m_line_detect_mode = (m_resolution_scale > 1) ? g_settings.gpu_line_detect_mode : GPULineDetectMode::Disabled;
|
m_line_detect_mode = (m_resolution_scale > 1) ? g_settings.gpu_line_detect_mode : GPULineDetectMode::Disabled;
|
||||||
m_clamp_uvs = clamp_uvs;
|
m_clamp_uvs = clamp_uvs;
|
||||||
|
@ -646,12 +653,14 @@ void GPU_HW::PrintSettingsToLog()
|
||||||
INFO_LOG("Multisampling: {}x{}", m_multisamples, m_per_sample_shading ? " (per sample shading)" : "");
|
INFO_LOG("Multisampling: {}x{}", m_multisamples, m_per_sample_shading ? " (per sample shading)" : "");
|
||||||
INFO_LOG("Dithering: {}{}", m_true_color ? "Disabled" : "Enabled",
|
INFO_LOG("Dithering: {}{}", m_true_color ? "Disabled" : "Enabled",
|
||||||
(!m_true_color && m_scaled_dithering) ? " (Scaled)" : ((m_true_color && m_debanding) ? " (Debanding)" : ""));
|
(!m_true_color && m_scaled_dithering) ? " (Scaled)" : ((m_true_color && m_debanding) ? " (Debanding)" : ""));
|
||||||
|
INFO_LOG("Force round texture coordinates: {}", m_force_round_texcoords ? "Enabled" : "Disabled");
|
||||||
INFO_LOG("Texture Filtering: {}", Settings::GetTextureFilterDisplayName(m_texture_filtering));
|
INFO_LOG("Texture Filtering: {}", Settings::GetTextureFilterDisplayName(m_texture_filtering));
|
||||||
INFO_LOG("Dual-source blending: {}", m_supports_dual_source_blend ? "Supported" : "Not supported");
|
INFO_LOG("Dual-source blending: {}", m_supports_dual_source_blend ? "Supported" : "Not supported");
|
||||||
INFO_LOG("Clamping UVs: {}", m_clamp_uvs ? "YES" : "NO");
|
INFO_LOG("Clamping UVs: {}", m_clamp_uvs ? "YES" : "NO");
|
||||||
INFO_LOG("Depth buffer: {}", m_pgxp_depth_buffer ? "YES" : "NO");
|
INFO_LOG("Depth buffer: {}", m_pgxp_depth_buffer ? "YES" : "NO");
|
||||||
INFO_LOG("Downsampling: {}", Settings::GetDownsampleModeDisplayName(m_downsample_mode));
|
INFO_LOG("Downsampling: {}", Settings::GetDownsampleModeDisplayName(m_downsample_mode));
|
||||||
INFO_LOG("Wireframe rendering: {}", Settings::GetGPUWireframeModeDisplayName(m_wireframe_mode));
|
INFO_LOG("Wireframe rendering: {}", Settings::GetGPUWireframeModeDisplayName(m_wireframe_mode));
|
||||||
|
INFO_LOG("Line detection: {}", Settings::GetLineDetectModeDisplayName(m_line_detect_mode));
|
||||||
INFO_LOG("Using software renderer for readbacks: {}", m_sw_renderer ? "YES" : "NO");
|
INFO_LOG("Using software renderer for readbacks: {}", m_sw_renderer ? "YES" : "NO");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,8 +867,9 @@ bool GPU_HW::CompilePipelines()
|
||||||
{
|
{
|
||||||
const std::string fs = shadergen.GenerateBatchFragmentShader(
|
const std::string fs = shadergen.GenerateBatchFragmentShader(
|
||||||
static_cast<BatchRenderMode>(render_mode), static_cast<GPUTransparencyMode>(transparency_mode),
|
static_cast<BatchRenderMode>(render_mode), static_cast<GPUTransparencyMode>(transparency_mode),
|
||||||
static_cast<GPUTextureMode>(texture_mode), m_texture_filtering, ConvertToBoolUnchecked(dithering),
|
static_cast<BatchTextureMode>(texture_mode), m_texture_filtering, m_force_round_texcoords,
|
||||||
ConvertToBoolUnchecked(interlacing), ConvertToBoolUnchecked(check_mask));
|
ConvertToBoolUnchecked(dithering), ConvertToBoolUnchecked(interlacing),
|
||||||
|
ConvertToBoolUnchecked(check_mask));
|
||||||
|
|
||||||
if (!(batch_fragment_shaders[render_mode][transparency_mode][texture_mode][check_mask][dithering]
|
if (!(batch_fragment_shaders[render_mode][transparency_mode][texture_mode][check_mask][dithering]
|
||||||
[interlacing] = g_gpu_device->CreateShader(GPUShaderStage::Fragment,
|
[interlacing] = g_gpu_device->CreateShader(GPUShaderStage::Fragment,
|
||||||
|
@ -936,7 +946,7 @@ bool GPU_HW::CompilePipelines()
|
||||||
{
|
{
|
||||||
for (u8 check_mask = 0; check_mask < 2; check_mask++)
|
for (u8 check_mask = 0; check_mask < 2; check_mask++)
|
||||||
{
|
{
|
||||||
const bool textured = (static_cast<GPUTextureMode>(texture_mode) != GPUTextureMode::Disabled);
|
const bool textured = (static_cast<BatchTextureMode>(texture_mode) != BatchTextureMode::Disabled);
|
||||||
const bool use_shader_blending =
|
const bool use_shader_blending =
|
||||||
(render_mode == static_cast<u8>(BatchRenderMode::ShaderBlend) &&
|
(render_mode == static_cast<u8>(BatchRenderMode::ShaderBlend) &&
|
||||||
((textured &&
|
((textured &&
|
||||||
|
@ -2498,7 +2508,7 @@ ALWAYS_INLINE_RELEASE bool GPU_HW::NeedsTwoPassRendering() const
|
||||||
// We need two-pass rendering when using BG-FG blending and texturing, as the transparency can be enabled
|
// We need two-pass rendering when using BG-FG blending and texturing, as the transparency can be enabled
|
||||||
// on a per-pixel basis, and the opaque pixels shouldn't be blended at all.
|
// on a per-pixel basis, and the opaque pixels shouldn't be blended at all.
|
||||||
|
|
||||||
return (m_batch.texture_mode != GPUTextureMode::Disabled &&
|
return (m_batch.texture_mode != BatchTextureMode::Disabled &&
|
||||||
(m_batch.transparency_mode == GPUTransparencyMode::BackgroundMinusForeground ||
|
(m_batch.transparency_mode == GPUTransparencyMode::BackgroundMinusForeground ||
|
||||||
(!m_supports_dual_source_blend && m_batch.transparency_mode != GPUTransparencyMode::Disabled)));
|
(!m_supports_dual_source_blend && m_batch.transparency_mode != GPUTransparencyMode::Disabled)));
|
||||||
}
|
}
|
||||||
|
@ -2970,7 +2980,7 @@ void GPU_HW::DispatchRenderCommand()
|
||||||
{
|
{
|
||||||
const GPURenderCommand rc{m_render_command.bits};
|
const GPURenderCommand rc{m_render_command.bits};
|
||||||
|
|
||||||
GPUTextureMode texture_mode = GPUTextureMode::Disabled;
|
BatchTextureMode texture_mode = BatchTextureMode::Disabled;
|
||||||
if (rc.IsTexturingEnabled())
|
if (rc.IsTexturingEnabled())
|
||||||
{
|
{
|
||||||
// texture page changed - check that the new page doesn't intersect the drawing area
|
// texture page changed - check that the new page doesn't intersect the drawing area
|
||||||
|
@ -3030,9 +3040,9 @@ void GPU_HW::DispatchRenderCommand()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
texture_mode = (m_draw_mode.mode_reg.texture_mode == GPUTextureMode::Reserved_Direct16Bit2) ?
|
texture_mode = (m_draw_mode.mode_reg.texture_mode == GPUTextureMode::Reserved_Direct16Bit) ?
|
||||||
GPUTextureMode::Direct16Bit :
|
BatchTextureMode::Direct16Bit :
|
||||||
m_draw_mode.mode_reg.texture_mode;
|
static_cast<BatchTextureMode>(m_draw_mode.mode_reg.texture_mode.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
// has any state changed which requires a new batch?
|
// has any state changed which requires a new batch?
|
||||||
|
@ -3055,7 +3065,7 @@ void GPU_HW::DispatchRenderCommand()
|
||||||
// transparency mode change
|
// transparency mode change
|
||||||
const bool check_mask_before_draw = m_GPUSTAT.check_mask_before_draw;
|
const bool check_mask_before_draw = m_GPUSTAT.check_mask_before_draw;
|
||||||
if (transparency_mode != GPUTransparencyMode::Disabled &&
|
if (transparency_mode != GPUTransparencyMode::Disabled &&
|
||||||
(texture_mode == GPUTextureMode::Disabled || !NeedsShaderBlending(transparency_mode, check_mask_before_draw)))
|
(texture_mode == BatchTextureMode::Disabled || !NeedsShaderBlending(transparency_mode, check_mask_before_draw)))
|
||||||
{
|
{
|
||||||
static constexpr float transparent_alpha[4][2] = {{0.5f, 0.5f}, {1.0f, 1.0f}, {1.0f, 1.0f}, {0.25f, 1.0f}};
|
static constexpr float transparent_alpha[4][2] = {{0.5f, 0.5f}, {1.0f, 1.0f}, {1.0f, 1.0f}, {0.25f, 1.0f}};
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,19 @@ public:
|
||||||
ShaderBlend
|
ShaderBlend
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class BatchTextureMode : u8
|
||||||
|
{
|
||||||
|
Palette4Bit,
|
||||||
|
Palette8Bit,
|
||||||
|
Direct16Bit,
|
||||||
|
Disabled,
|
||||||
|
|
||||||
|
MaxCount,
|
||||||
|
};
|
||||||
|
static_assert(static_cast<u8>(BatchTextureMode::Palette4Bit) == static_cast<u8>(GPUTextureMode::Palette4Bit) &&
|
||||||
|
static_cast<u8>(BatchTextureMode::Palette8Bit) == static_cast<u8>(GPUTextureMode::Palette8Bit) &&
|
||||||
|
static_cast<u8>(BatchTextureMode::Direct16Bit) == static_cast<u8>(GPUTextureMode::Direct16Bit));
|
||||||
|
|
||||||
GPU_HW();
|
GPU_HW();
|
||||||
~GPU_HW() override;
|
~GPU_HW() override;
|
||||||
|
|
||||||
|
@ -58,7 +71,7 @@ private:
|
||||||
MAX_BATCH_VERTEX_COUNTER_IDS = 65536 - 2,
|
MAX_BATCH_VERTEX_COUNTER_IDS = 65536 - 2,
|
||||||
MAX_VERTICES_FOR_RECTANGLE = 6 * (((MAX_PRIMITIVE_WIDTH + (TEXTURE_PAGE_WIDTH - 1)) / TEXTURE_PAGE_WIDTH) + 1u) *
|
MAX_VERTICES_FOR_RECTANGLE = 6 * (((MAX_PRIMITIVE_WIDTH + (TEXTURE_PAGE_WIDTH - 1)) / TEXTURE_PAGE_WIDTH) + 1u) *
|
||||||
(((MAX_PRIMITIVE_HEIGHT + (TEXTURE_PAGE_HEIGHT - 1)) / TEXTURE_PAGE_HEIGHT) + 1u),
|
(((MAX_PRIMITIVE_HEIGHT + (TEXTURE_PAGE_HEIGHT - 1)) / TEXTURE_PAGE_HEIGHT) + 1u),
|
||||||
NUM_TEXTURE_MODES = 4,
|
NUM_TEXTURE_MODES = static_cast<u32>(BatchTextureMode::MaxCount),
|
||||||
};
|
};
|
||||||
enum : u8
|
enum : u8
|
||||||
{
|
{
|
||||||
|
@ -88,7 +101,7 @@ private:
|
||||||
|
|
||||||
struct BatchConfig
|
struct BatchConfig
|
||||||
{
|
{
|
||||||
GPUTextureMode texture_mode = GPUTextureMode::Disabled;
|
BatchTextureMode texture_mode = BatchTextureMode::Disabled;
|
||||||
GPUTransparencyMode transparency_mode = GPUTransparencyMode::Disabled;
|
GPUTransparencyMode transparency_mode = GPUTransparencyMode::Disabled;
|
||||||
bool dithering = false;
|
bool dithering = false;
|
||||||
bool interlacing = false;
|
bool interlacing = false;
|
||||||
|
@ -235,6 +248,7 @@ private:
|
||||||
bool m_per_sample_shading : 1 = false;
|
bool m_per_sample_shading : 1 = false;
|
||||||
bool m_scaled_dithering : 1 = false;
|
bool m_scaled_dithering : 1 = false;
|
||||||
bool m_disable_color_perspective : 1 = false;
|
bool m_disable_color_perspective : 1 = false;
|
||||||
|
bool m_force_round_texcoords = false;
|
||||||
|
|
||||||
GPUTextureFilter m_texture_filtering = GPUTextureFilter::Nearest;
|
GPUTextureFilter m_texture_filtering = GPUTextureFilter::Nearest;
|
||||||
GPULineDetectMode m_line_detect_mode = GPULineDetectMode::Disabled;
|
GPULineDetectMode m_line_detect_mode = GPULineDetectMode::Disabled;
|
||||||
|
|
|
@ -630,15 +630,14 @@ void FilteredSampleFromVRAM(uint4 texpage, float2 coords, float4 uv_limits,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(GPU_HW::BatchRenderMode render_mode,
|
std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(
|
||||||
GPUTransparencyMode transparency, GPUTextureMode texture_mode,
|
GPU_HW::BatchRenderMode render_mode, GPUTransparencyMode transparency, GPU_HW::BatchTextureMode texture_mode,
|
||||||
GPUTextureFilter texture_filtering, bool dithering,
|
GPUTextureFilter texture_filtering, bool force_round_texcoords, bool dithering, bool interlacing, bool check_mask)
|
||||||
bool interlacing, bool check_mask)
|
|
||||||
{
|
{
|
||||||
// TODO: don't write depth for shader blend
|
// TODO: don't write depth for shader blend
|
||||||
DebugAssert(transparency == GPUTransparencyMode::Disabled || render_mode == GPU_HW::BatchRenderMode::ShaderBlend);
|
DebugAssert(transparency == GPUTransparencyMode::Disabled || render_mode == GPU_HW::BatchRenderMode::ShaderBlend);
|
||||||
|
|
||||||
const bool textured = (texture_mode != GPUTextureMode::Disabled);
|
const bool textured = (texture_mode != GPU_HW::BatchTextureMode::Disabled);
|
||||||
const bool shader_blending = (render_mode == GPU_HW::BatchRenderMode::ShaderBlend &&
|
const bool shader_blending = (render_mode == GPU_HW::BatchRenderMode::ShaderBlend &&
|
||||||
(transparency != GPUTransparencyMode::Disabled || check_mask));
|
(transparency != GPUTransparencyMode::Disabled || check_mask));
|
||||||
const bool use_dual_source = (!shader_blending && m_supports_dual_source_blend &&
|
const bool use_dual_source = (!shader_blending && m_supports_dual_source_blend &&
|
||||||
|
@ -656,9 +655,10 @@ std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(GPU_HW::BatchRenderMod
|
||||||
DefineMacro(ss, "CHECK_MASK_BIT", check_mask);
|
DefineMacro(ss, "CHECK_MASK_BIT", check_mask);
|
||||||
DefineMacro(ss, "TEXTURED", textured);
|
DefineMacro(ss, "TEXTURED", textured);
|
||||||
DefineMacro(ss, "PALETTE",
|
DefineMacro(ss, "PALETTE",
|
||||||
texture_mode == GPUTextureMode::Palette4Bit || texture_mode == GPUTextureMode::Palette8Bit);
|
texture_mode == GPU_HW::BatchTextureMode::Palette4Bit ||
|
||||||
DefineMacro(ss, "PALETTE_4_BIT", texture_mode == GPUTextureMode::Palette4Bit);
|
texture_mode == GPU_HW::BatchTextureMode::Palette8Bit);
|
||||||
DefineMacro(ss, "PALETTE_8_BIT", texture_mode == GPUTextureMode::Palette8Bit);
|
DefineMacro(ss, "PALETTE_4_BIT", texture_mode == GPU_HW::BatchTextureMode::Palette4Bit);
|
||||||
|
DefineMacro(ss, "PALETTE_8_BIT", texture_mode == GPU_HW::BatchTextureMode::Palette8Bit);
|
||||||
DefineMacro(ss, "DITHERING", dithering);
|
DefineMacro(ss, "DITHERING", dithering);
|
||||||
DefineMacro(ss, "DITHERING_SCALED", m_scaled_dithering);
|
DefineMacro(ss, "DITHERING_SCALED", m_scaled_dithering);
|
||||||
// Debanding requires true color to work correctly.
|
// Debanding requires true color to work correctly.
|
||||||
|
@ -669,6 +669,7 @@ std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(GPU_HW::BatchRenderMod
|
||||||
DefineMacro(ss, "UV_LIMITS", m_uv_limits);
|
DefineMacro(ss, "UV_LIMITS", m_uv_limits);
|
||||||
DefineMacro(ss, "USE_DUAL_SOURCE", use_dual_source);
|
DefineMacro(ss, "USE_DUAL_SOURCE", use_dual_source);
|
||||||
DefineMacro(ss, "WRITE_MASK_AS_DEPTH", m_write_mask_as_depth);
|
DefineMacro(ss, "WRITE_MASK_AS_DEPTH", m_write_mask_as_depth);
|
||||||
|
DefineMacro(ss, "FORCE_ROUND_TEXCOORDS", force_round_texcoords);
|
||||||
|
|
||||||
WriteCommonFunctions(ss);
|
WriteCommonFunctions(ss);
|
||||||
WriteBatchUniformBuffer(ss);
|
WriteBatchUniformBuffer(ss);
|
||||||
|
@ -727,7 +728,7 @@ uint2 FloatToIntegerCoords(float2 coords)
|
||||||
{
|
{
|
||||||
// With the vertex offset applied at 1x resolution scale, we want to round the texture coordinates.
|
// With the vertex offset applied at 1x resolution scale, we want to round the texture coordinates.
|
||||||
// Floor them otherwise, as it currently breaks when upscaling as the vertex offset is not applied.
|
// Floor them otherwise, as it currently breaks when upscaling as the vertex offset is not applied.
|
||||||
return uint2((RESOLUTION_SCALE == 1u) ? roundEven(coords) : floor(coords));
|
return uint2((RESOLUTION_SCALE == 1u || FORCE_ROUND_TEXCOORDS != 0) ? roundEven(coords) : floor(coords));
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 SampleFromVRAM(uint4 texpage, float2 coords)
|
float4 SampleFromVRAM(uint4 texpage, float2 coords)
|
||||||
|
|
|
@ -16,8 +16,9 @@ public:
|
||||||
|
|
||||||
std::string GenerateBatchVertexShader(bool textured, bool pgxp_depth);
|
std::string GenerateBatchVertexShader(bool textured, bool pgxp_depth);
|
||||||
std::string GenerateBatchFragmentShader(GPU_HW::BatchRenderMode render_mode, GPUTransparencyMode transparency,
|
std::string GenerateBatchFragmentShader(GPU_HW::BatchRenderMode render_mode, GPUTransparencyMode transparency,
|
||||||
GPUTextureMode texture_mode, GPUTextureFilter texture_filtering,
|
GPU_HW::BatchTextureMode texture_mode, GPUTextureFilter texture_filtering,
|
||||||
bool dithering, bool interlacing, bool check_mask);
|
bool force_round_texcoords, bool dithering, bool interlacing,
|
||||||
|
bool check_mask);
|
||||||
std::string GenerateWireframeGeometryShader();
|
std::string GenerateWireframeGeometryShader();
|
||||||
std::string GenerateWireframeFragmentShader();
|
std::string GenerateWireframeFragmentShader();
|
||||||
std::string GenerateVRAMReadFragmentShader();
|
std::string GenerateVRAMReadFragmentShader();
|
||||||
|
|
|
@ -53,8 +53,7 @@ enum class GPUTextureMode : u8
|
||||||
Palette4Bit = 0,
|
Palette4Bit = 0,
|
||||||
Palette8Bit = 1,
|
Palette8Bit = 1,
|
||||||
Direct16Bit = 2,
|
Direct16Bit = 2,
|
||||||
Reserved_Direct16Bit2 = 3, // Not used.
|
Reserved_Direct16Bit = 3, // Not used.
|
||||||
Disabled = 3 // Not a register value
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IMPLEMENT_ENUM_CLASS_BITWISE_OPERATORS(GPUTextureMode);
|
IMPLEMENT_ENUM_CLASS_BITWISE_OPERATORS(GPUTextureMode);
|
||||||
|
|
|
@ -197,6 +197,7 @@ void Settings::Load(SettingsInterface& si)
|
||||||
gpu_true_color = si.GetBoolValue("GPU", "TrueColor", true);
|
gpu_true_color = si.GetBoolValue("GPU", "TrueColor", true);
|
||||||
gpu_debanding = si.GetBoolValue("GPU", "Debanding", false);
|
gpu_debanding = si.GetBoolValue("GPU", "Debanding", false);
|
||||||
gpu_scaled_dithering = si.GetBoolValue("GPU", "ScaledDithering", true);
|
gpu_scaled_dithering = si.GetBoolValue("GPU", "ScaledDithering", true);
|
||||||
|
gpu_force_round_texcoords = si.GetBoolValue("GPU", "ForceRoundTextureCoordinates", false);
|
||||||
gpu_texture_filter =
|
gpu_texture_filter =
|
||||||
ParseTextureFilterName(
|
ParseTextureFilterName(
|
||||||
si.GetStringValue("GPU", "TextureFilter", GetTextureFilterName(DEFAULT_GPU_TEXTURE_FILTER)).c_str())
|
si.GetStringValue("GPU", "TextureFilter", GetTextureFilterName(DEFAULT_GPU_TEXTURE_FILTER)).c_str())
|
||||||
|
@ -495,6 +496,7 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const
|
||||||
si.SetBoolValue("GPU", "TrueColor", gpu_true_color);
|
si.SetBoolValue("GPU", "TrueColor", gpu_true_color);
|
||||||
si.SetBoolValue("GPU", "Debanding", gpu_debanding);
|
si.SetBoolValue("GPU", "Debanding", gpu_debanding);
|
||||||
si.SetBoolValue("GPU", "ScaledDithering", gpu_scaled_dithering);
|
si.SetBoolValue("GPU", "ScaledDithering", gpu_scaled_dithering);
|
||||||
|
si.SetBoolValue("GPU", "ForceRoundTextureCoordinates", gpu_force_round_texcoords);
|
||||||
si.SetStringValue("GPU", "TextureFilter", GetTextureFilterName(gpu_texture_filter));
|
si.SetStringValue("GPU", "TextureFilter", GetTextureFilterName(gpu_texture_filter));
|
||||||
si.SetStringValue("GPU", "LineDetectMode", GetLineDetectModeName(gpu_line_detect_mode));
|
si.SetStringValue("GPU", "LineDetectMode", GetLineDetectModeName(gpu_line_detect_mode));
|
||||||
si.SetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(gpu_downsample_mode));
|
si.SetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(gpu_downsample_mode));
|
||||||
|
@ -701,6 +703,7 @@ void Settings::FixIncompatibleSettings(bool display_osd_messages)
|
||||||
g_settings.gpu_true_color = false;
|
g_settings.gpu_true_color = false;
|
||||||
g_settings.gpu_debanding = false;
|
g_settings.gpu_debanding = false;
|
||||||
g_settings.gpu_scaled_dithering = false;
|
g_settings.gpu_scaled_dithering = false;
|
||||||
|
g_settings.gpu_force_round_texcoords = false;
|
||||||
g_settings.gpu_texture_filter = GPUTextureFilter::Nearest;
|
g_settings.gpu_texture_filter = GPUTextureFilter::Nearest;
|
||||||
g_settings.gpu_line_detect_mode = GPULineDetectMode::Disabled;
|
g_settings.gpu_line_detect_mode = GPULineDetectMode::Disabled;
|
||||||
g_settings.gpu_disable_interlacing = false;
|
g_settings.gpu_disable_interlacing = false;
|
||||||
|
|
|
@ -117,6 +117,7 @@ struct Settings
|
||||||
bool gpu_true_color : 1 = true;
|
bool gpu_true_color : 1 = true;
|
||||||
bool gpu_debanding : 1 = false;
|
bool gpu_debanding : 1 = false;
|
||||||
bool gpu_scaled_dithering : 1 = true;
|
bool gpu_scaled_dithering : 1 = true;
|
||||||
|
bool gpu_force_round_texcoords : 1 = false;
|
||||||
GPUTextureFilter gpu_texture_filter = DEFAULT_GPU_TEXTURE_FILTER;
|
GPUTextureFilter gpu_texture_filter = DEFAULT_GPU_TEXTURE_FILTER;
|
||||||
GPULineDetectMode gpu_line_detect_mode = DEFAULT_GPU_LINE_DETECT_MODE;
|
GPULineDetectMode gpu_line_detect_mode = DEFAULT_GPU_LINE_DETECT_MODE;
|
||||||
GPUDownsampleMode gpu_downsample_mode = DEFAULT_GPU_DOWNSAMPLE_MODE;
|
GPUDownsampleMode gpu_downsample_mode = DEFAULT_GPU_DOWNSAMPLE_MODE;
|
||||||
|
|
|
@ -4015,6 +4015,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
||||||
g_settings.gpu_true_color != old_settings.gpu_true_color ||
|
g_settings.gpu_true_color != old_settings.gpu_true_color ||
|
||||||
g_settings.gpu_debanding != old_settings.gpu_debanding ||
|
g_settings.gpu_debanding != old_settings.gpu_debanding ||
|
||||||
g_settings.gpu_scaled_dithering != old_settings.gpu_scaled_dithering ||
|
g_settings.gpu_scaled_dithering != old_settings.gpu_scaled_dithering ||
|
||||||
|
g_settings.gpu_force_round_texcoords != old_settings.gpu_force_round_texcoords ||
|
||||||
g_settings.gpu_texture_filter != old_settings.gpu_texture_filter ||
|
g_settings.gpu_texture_filter != old_settings.gpu_texture_filter ||
|
||||||
g_settings.gpu_line_detect_mode != old_settings.gpu_line_detect_mode ||
|
g_settings.gpu_line_detect_mode != old_settings.gpu_line_detect_mode ||
|
||||||
g_settings.gpu_disable_interlacing != old_settings.gpu_disable_interlacing ||
|
g_settings.gpu_disable_interlacing != old_settings.gpu_disable_interlacing ||
|
||||||
|
|
|
@ -89,7 +89,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||||
connect(m_ui.adapter, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
connect(m_ui.adapter, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||||
&GraphicsSettingsWidget::onAdapterChanged);
|
&GraphicsSettingsWidget::onAdapterChanged);
|
||||||
connect(m_ui.resolutionScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
connect(m_ui.resolutionScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||||
&GraphicsSettingsWidget::onTrueColorChanged);
|
&GraphicsSettingsWidget::updateResolutionDependentOptions);
|
||||||
|
connect(m_ui.textureFiltering, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||||
|
&GraphicsSettingsWidget::updateResolutionDependentOptions);
|
||||||
connect(m_ui.displayAspectRatio, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
connect(m_ui.displayAspectRatio, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||||
&GraphicsSettingsWidget::onAspectRatioChanged);
|
&GraphicsSettingsWidget::onAspectRatioChanged);
|
||||||
connect(m_ui.gpuDownsampleMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
connect(m_ui.gpuDownsampleMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||||
|
@ -143,6 +145,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", false);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useSoftwareRendererForReadbacks, "GPU",
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useSoftwareRendererForReadbacks, "GPU",
|
||||||
"UseSoftwareRendererForReadbacks", false);
|
"UseSoftwareRendererForReadbacks", false);
|
||||||
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceRoundedTexcoords, "GPU", "ForceRoundTextureCoordinates",
|
||||||
|
false);
|
||||||
|
|
||||||
connect(m_ui.fullscreenMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
connect(m_ui.fullscreenMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||||
&GraphicsSettingsWidget::onFullscreenModeChanged);
|
&GraphicsSettingsWidget::onFullscreenModeChanged);
|
||||||
|
@ -230,7 +234,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||||
updateRendererDependentOptions();
|
updateRendererDependentOptions();
|
||||||
onAspectRatioChanged();
|
onAspectRatioChanged();
|
||||||
onDownsampleModeChanged();
|
onDownsampleModeChanged();
|
||||||
onTrueColorChanged();
|
updateResolutionDependentOptions();
|
||||||
onEnableAnyTextureReplacementsChanged();
|
onEnableAnyTextureReplacementsChanged();
|
||||||
onEnableVRAMWriteDumpingChanged();
|
onEnableVRAMWriteDumpingChanged();
|
||||||
onShowDebugSettingsChanged(QtHost::ShouldShowDebugOptions());
|
onShowDebugSettingsChanged(QtHost::ShouldShowDebugOptions());
|
||||||
|
@ -373,6 +377,10 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||||
m_ui.useSoftwareRendererForReadbacks, tr("Software Renderer Readbacks"), tr("Unchecked"),
|
m_ui.useSoftwareRendererForReadbacks, tr("Software Renderer Readbacks"), tr("Unchecked"),
|
||||||
tr("Runs the software renderer in parallel for VRAM readbacks. On some systems, this may result in greater "
|
tr("Runs the software renderer in parallel for VRAM readbacks. On some systems, this may result in greater "
|
||||||
"performance when using graphical enhancements with the hardware renderer."));
|
"performance when using graphical enhancements with the hardware renderer."));
|
||||||
|
dialog->registerWidgetHelp(
|
||||||
|
m_ui.forceRoundedTexcoords, tr("Round Upscaled Texture Coordinates"), tr("Unchecked"),
|
||||||
|
tr("Rounds texture coordinates instead of flooring when upscaling. Can fix misaligned textures in some games, but "
|
||||||
|
"break others, and is incompatible with texture filtering."));
|
||||||
|
|
||||||
// PGXP Tab
|
// PGXP Tab
|
||||||
|
|
||||||
|
@ -796,6 +804,20 @@ void GraphicsSettingsWidget::onAspectRatioChanged()
|
||||||
m_ui.customAspectRatioSeparator->setVisible(is_custom);
|
m_ui.customAspectRatioSeparator->setVisible(is_custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphicsSettingsWidget::updateResolutionDependentOptions()
|
||||||
|
{
|
||||||
|
const int scale = m_dialog->getEffectiveIntValue("GPU", "ResolutionScale", 1);
|
||||||
|
const GPUTextureFilter texture_filtering =
|
||||||
|
Settings::ParseTextureFilterName(
|
||||||
|
m_dialog
|
||||||
|
->getEffectiveStringValue("GPU", "TextureFilter",
|
||||||
|
Settings::GetTextureFilterName(Settings::DEFAULT_GPU_TEXTURE_FILTER))
|
||||||
|
.c_str())
|
||||||
|
.value_or(Settings::DEFAULT_GPU_TEXTURE_FILTER);
|
||||||
|
m_ui.forceRoundedTexcoords->setEnabled(scale > 1 && texture_filtering == GPUTextureFilter::Nearest);
|
||||||
|
onTrueColorChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void GraphicsSettingsWidget::onMSAAModeChanged()
|
void GraphicsSettingsWidget::onMSAAModeChanged()
|
||||||
{
|
{
|
||||||
const int index = m_ui.msaaMode->currentIndex();
|
const int index = m_ui.msaaMode->currentIndex();
|
||||||
|
@ -816,8 +838,8 @@ void GraphicsSettingsWidget::onMSAAModeChanged()
|
||||||
|
|
||||||
void GraphicsSettingsWidget::onTrueColorChanged()
|
void GraphicsSettingsWidget::onTrueColorChanged()
|
||||||
{
|
{
|
||||||
const int resolution_scale = m_ui.resolutionScale->currentIndex();
|
const int resolution_scale = m_dialog->getEffectiveIntValue("GPU", "ResolutionScale", 1);
|
||||||
const bool true_color = m_ui.trueColor->isChecked();
|
const bool true_color = m_dialog->getEffectiveBoolValue("GPU", "TrueColor", false);
|
||||||
const bool allow_scaled_dithering = (resolution_scale != 1 && !true_color);
|
const bool allow_scaled_dithering = (resolution_scale != 1 && !true_color);
|
||||||
const bool allow_debanding = true_color;
|
const bool allow_debanding = true_color;
|
||||||
m_ui.scaledDithering->setEnabled(allow_scaled_dithering);
|
m_ui.scaledDithering->setEnabled(allow_scaled_dithering);
|
||||||
|
|
|
@ -29,6 +29,7 @@ private Q_SLOTS:
|
||||||
|
|
||||||
void onAdapterChanged();
|
void onAdapterChanged();
|
||||||
void onAspectRatioChanged();
|
void onAspectRatioChanged();
|
||||||
|
void updateResolutionDependentOptions();
|
||||||
void onMSAAModeChanged();
|
void onMSAAModeChanged();
|
||||||
void onTrueColorChanged();
|
void onTrueColorChanged();
|
||||||
void onDownsampleModeChanged();
|
void onDownsampleModeChanged();
|
||||||
|
|
|
@ -468,10 +468,10 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="2">
|
<item row="2" column="0" colspan="2">
|
||||||
<layout class="QGridLayout" name="gridLayout_5">
|
<layout class="QGridLayout" name="gridLayout_5">
|
||||||
<item row="0" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="debanding">
|
<widget class="QCheckBox" name="gpuThread">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>True Color Debanding</string>
|
<string>Threaded Rendering</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -489,10 +489,17 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QCheckBox" name="gpuThread">
|
<widget class="QCheckBox" name="debanding">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Threaded Rendering</string>
|
<string>True Color Debanding</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="forceRoundedTexcoords">
|
||||||
|
<property name="text">
|
||||||
|
<string>Round Upscaled Texture Coordinates</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
Loading…
Reference in a new issue