mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-25 23:25:41 +00:00
GPU/HW: Add quad line detection (Wild Arms 2)
This commit is contained in:
parent
250fb56838
commit
713d396a7e
|
@ -43128,8 +43128,9 @@ SLES-00132:
|
|||
controllers:
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "GT Interactive / Williams Entertainment"
|
||||
developer: "Midway Studios San Diego"
|
||||
|
@ -43151,8 +43152,9 @@ SLPS-00308:
|
|||
controllers:
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "Soft Bank"
|
||||
developer: "Midway Studios San Diego"
|
||||
|
@ -43172,12 +43174,12 @@ SLUS-00077:
|
|||
compatibility:
|
||||
rating: NoIssues
|
||||
versionTested: "0.1-908-g9f22684"
|
||||
upscalingIssues: "Broken when upscaling"
|
||||
controllers:
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "GT Interactive / Williams Entertainment"
|
||||
developer: "Midway Studios San Diego"
|
||||
|
@ -46145,8 +46147,9 @@ SLES-00703:
|
|||
- AnalogController
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "GT Interactive"
|
||||
developer: "3D Realms Entertainment"
|
||||
|
@ -46167,8 +46170,9 @@ SLES-00987:
|
|||
- AnalogController
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "GT Interactive"
|
||||
developer: "3D Realms Entertainment"
|
||||
|
@ -46186,8 +46190,9 @@ SLES-00987:
|
|||
SLED-01027:
|
||||
name: "Duke Nukem (France) (Demo)"
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled rendering.
|
||||
SLES-03405:
|
||||
name: "Duke Nukem - Land of the Babes (Europe) (En,Fr,De,Es,It)"
|
||||
controllers:
|
||||
|
@ -46360,8 +46365,9 @@ SLPS-01557:
|
|||
- AnalogController
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "King Record Co. Ltd"
|
||||
developer: "3D Realms Entertainment"
|
||||
|
@ -46385,8 +46391,9 @@ SLUS-00355:
|
|||
- AnalogController
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "GT Interactive"
|
||||
developer: "3D Realms Entertainment"
|
||||
|
@ -54792,8 +54799,9 @@ SLES-00487:
|
|||
- DigitalController
|
||||
- PlayStationMouse
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "GT Interactive / Williams Entertainment"
|
||||
developer: "id Software, Inc."
|
||||
|
@ -54814,8 +54822,9 @@ SLPS-00727:
|
|||
- DigitalController
|
||||
- PlayStationMouse
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "Soft Bank"
|
||||
developer: "id Software, Inc."
|
||||
|
@ -54835,13 +54844,13 @@ SLUS-00331:
|
|||
compatibility:
|
||||
rating: NoIssues
|
||||
versionTested: "0.1-986-gfc911de1"
|
||||
upscalingIssues: "Rendering is broken with any upscaling."
|
||||
controllers:
|
||||
- DigitalController
|
||||
- PlayStationMouse
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "GT Interactive / Williams Entertainment"
|
||||
developer: "id Software, Inc."
|
||||
|
@ -149474,6 +149483,8 @@ SCES-00577:
|
|||
versionTested: "0.1-2949-gcd2c581f"
|
||||
controllers:
|
||||
- DigitalController
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled water rendering.
|
||||
metadata:
|
||||
publisher: "Sony Computer Entertaiment Europe"
|
||||
developer: "Namco"
|
||||
|
@ -149493,9 +149504,10 @@ SLUS-00240:
|
|||
compatibility:
|
||||
rating: NoIssues
|
||||
versionTested: "0.1-1409-ge198e315"
|
||||
upscalingIssues: "Water error in Li Long stage (Issue #371)"
|
||||
controllers:
|
||||
- DigitalController
|
||||
settings:
|
||||
gpuLineDetectMode: BasicTriangles # Fixes upscaled water rendering.
|
||||
metadata:
|
||||
publisher: "Namco"
|
||||
developer: "Namco"
|
||||
|
@ -153089,8 +153101,9 @@ SLES-00585:
|
|||
controllers:
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, PGXP is not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: AggressiveTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "Lucasarts"
|
||||
developer: "Lucasarts / Big Bang Software, Inc"
|
||||
|
@ -153110,8 +153123,9 @@ SLES-00640:
|
|||
controllers:
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, PGXP is not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: AggressiveTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "Lucasarts"
|
||||
developer: "Lucasarts / Big Bang Software, Inc"
|
||||
|
@ -153132,8 +153146,9 @@ SLPS-00685:
|
|||
controllers:
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, PGXP is not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: AggressiveTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "Bullet-Proof Software"
|
||||
developer: "Lucasarts / Big Bang Software, Inc"
|
||||
|
@ -153153,8 +153168,9 @@ SLES-00646:
|
|||
controllers:
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, PGXP is not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: AggressiveTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "Erbe Software"
|
||||
developer: "Lucasarts / Big Bang Software, Inc"
|
||||
|
@ -153175,12 +153191,12 @@ SLUS-00297:
|
|||
compatibility:
|
||||
rating: NoIssues
|
||||
versionTested: "0.1-986-gfc911de1"
|
||||
upscalingIssues: "Rendering is broken when upscaling is used."
|
||||
controllers:
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
- DisablePGXP
|
||||
- DisablePGXP # 2.5D, PGXP is not beneficial.
|
||||
settings:
|
||||
gpuLineDetectMode: AggressiveTriangles # Fixes upscaled rendering.
|
||||
metadata:
|
||||
publisher: "Lucasarts"
|
||||
developer: "Lucasarts / Big Bang Software, Inc"
|
||||
|
@ -163808,6 +163824,8 @@ SLPS-00365:
|
|||
name: "Tekkyuu - True Pinball (Japan)"
|
||||
controllers:
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
metadata:
|
||||
publisher: "Ocean"
|
||||
developer: "Digital Illusions CE AB"
|
||||
|
@ -172671,6 +172689,8 @@ SLES-00052:
|
|||
name: "True Pinball (Europe)"
|
||||
controllers:
|
||||
- DigitalController
|
||||
traits:
|
||||
- DisableUpscaling
|
||||
metadata:
|
||||
publisher: "Ocean"
|
||||
developer: "Digital Illusions CE AB"
|
||||
|
@ -172695,6 +172715,7 @@ SLUS-00337:
|
|||
- DigitalController
|
||||
traits:
|
||||
- ForceInterlacing
|
||||
- DisableUpscaling
|
||||
metadata:
|
||||
publisher: "Ocean"
|
||||
developer: "Digital Illusions CE AB"
|
||||
|
@ -180948,6 +180969,8 @@ SCUS-94592:
|
|||
name: "Wild Arms 2 (USA) (Demo)"
|
||||
traits:
|
||||
- ForcePGXPCPUMode
|
||||
settings:
|
||||
gpuLineDetectMode: Quads
|
||||
SCUS-94484:
|
||||
name: "Wild Arms 2 (USA) (Disc 1)"
|
||||
discSet:
|
||||
|
@ -180962,6 +180985,8 @@ SCUS-94484:
|
|||
- DigitalController
|
||||
traits:
|
||||
- ForcePGXPCPUMode
|
||||
settings:
|
||||
gpuLineDetectMode: Quads
|
||||
metadata:
|
||||
publisher: "Sony"
|
||||
developer: "Media.Vision Entertainment / Contrail"
|
||||
|
@ -180987,6 +181012,8 @@ SCUS-94498:
|
|||
- DigitalController
|
||||
traits:
|
||||
- ForcePGXPCPUMode
|
||||
settings:
|
||||
gpuLineDetectMode: Quads
|
||||
metadata:
|
||||
publisher: "Sony"
|
||||
developer: "Media.Vision Entertainment / Contrail"
|
||||
|
@ -181007,6 +181034,8 @@ SCPS-45429:
|
|||
- DigitalController
|
||||
traits:
|
||||
- ForcePGXPCPUMode
|
||||
settings:
|
||||
gpuLineDetectMode: Quads
|
||||
codes:
|
||||
- SCPS-45429
|
||||
- SCPS-45430
|
||||
|
|
|
@ -2467,13 +2467,12 @@ void FullscreenUI::DrawSettingsWindow()
|
|||
static constexpr float ITEM_WIDTH = 25.0f;
|
||||
|
||||
static constexpr const char* global_icons[] = {
|
||||
ICON_FA_TV, ICON_FA_DICE_D20, ICON_FA_COGS, ICON_PF_MICROCHIP,
|
||||
ICON_PF_PICTURE, ICON_FA_MAGIC, ICON_PF_SOUND, ICON_PF_GAMEPAD_ALT,
|
||||
ICON_PF_KEYBOARD_ALT, ICON_PF_MEMORY_CARD, ICON_FA_TROPHY, ICON_FA_EXCLAMATION_TRIANGLE};
|
||||
static constexpr const char* per_game_icons[] = {
|
||||
ICON_FA_PARAGRAPH, ICON_FA_HDD, ICON_FA_COGS,
|
||||
ICON_PF_PICTURE, ICON_PF_SOUND, ICON_PF_GAMEPAD_ALT,
|
||||
ICON_PF_MEMORY_CARD, ICON_FA_TROPHY, ICON_FA_EXCLAMATION_TRIANGLE};
|
||||
ICON_FA_TV, ICON_FA_DICE_D20, ICON_FA_COGS, ICON_PF_MICROCHIP,
|
||||
ICON_PF_PICTURE, ICON_FA_MAGIC, ICON_PF_SOUND, ICON_PF_GAMEPAD_ALT,
|
||||
ICON_PF_KEYBOARD_ALT, ICON_PF_MEMORY_CARD, ICON_FA_TROPHY, ICON_FA_EXCLAMATION_TRIANGLE};
|
||||
static constexpr const char* per_game_icons[] = {ICON_FA_PARAGRAPH, ICON_FA_HDD, ICON_FA_COGS,
|
||||
ICON_PF_PICTURE, ICON_PF_SOUND, ICON_PF_GAMEPAD_ALT,
|
||||
ICON_PF_MEMORY_CARD, ICON_FA_TROPHY, ICON_FA_EXCLAMATION_TRIANGLE};
|
||||
static constexpr SettingsPage global_pages[] = {
|
||||
SettingsPage::Interface, SettingsPage::Console, SettingsPage::Emulation, SettingsPage::BIOS,
|
||||
SettingsPage::Display, SettingsPage::PostProcessing, SettingsPage::Audio, SettingsPage::Controller,
|
||||
|
@ -3908,6 +3907,13 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
|||
"GPU", "TextureFilter", Settings::DEFAULT_GPU_TEXTURE_FILTER, &Settings::ParseTextureFilterName,
|
||||
&Settings::GetTextureFilterName, &Settings::GetTextureFilterDisplayName, GPUTextureFilter::Count, is_hardware);
|
||||
|
||||
DrawEnumSetting(bsi, FSUI_CSTR("Line Detection"),
|
||||
FSUI_CSTR("Attempts to detect one pixel high/wide lines that rely on non-upscaled rasterization "
|
||||
"behavior, filling in gaps introduced by upscaling."),
|
||||
"GPU", "LineDetectMode", Settings::DEFAULT_GPU_LINE_DETECT_MODE, &Settings::ParseLineDetectModeName,
|
||||
&Settings::GetLineDetectModeName, &Settings::GetLineDetectModeDisplayName, GPULineDetectMode::Count,
|
||||
is_hardware);
|
||||
|
||||
DrawToggleSetting(bsi, FSUI_CSTR("True Color Rendering"),
|
||||
FSUI_CSTR("Disables dithering and uses the full 8 bits per channel of color information."), "GPU",
|
||||
"TrueColor", true, is_hardware);
|
||||
|
@ -6547,6 +6553,7 @@ TRANSLATE_NOOP("FullscreenUI", "Apply Image Patches");
|
|||
TRANSLATE_NOOP("FullscreenUI", "Apply Per-Game Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Are you sure you want to clear the current post-processing chain? All configuration will be lost.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Aspect Ratio");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Attempts to detect one pixel high/wide lines that rely on non-upscaled rasterization behavior, filling in gaps introduced by upscaling.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Attempts to map the selected port to a chosen controller.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Audio Backend");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Audio Control");
|
||||
|
@ -6777,6 +6784,7 @@ TRANSLATE_NOOP("FullscreenUI", "Leaderboard Notifications");
|
|||
TRANSLATE_NOOP("FullscreenUI", "Leaderboards");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Leaderboards are not enabled.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Limits how many frames are displayed to the screen. These frames are still rendered.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Line Detection");
|
||||
TRANSLATE_NOOP("FullscreenUI", "List Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Load Devices From Save States");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Load Profile");
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace GameDatabase {
|
|||
enum : u32
|
||||
{
|
||||
GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48,
|
||||
GAME_DATABASE_CACHE_VERSION = 6,
|
||||
GAME_DATABASE_CACHE_VERSION = 7,
|
||||
};
|
||||
|
||||
static Entry* GetMutableEntry(const std::string_view& serial);
|
||||
|
@ -184,6 +184,31 @@ static std::optional<T> GetOptionalTFromObject(const ryml::ConstNodeRef& object,
|
|||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static std::optional<T> ParseOptionalTFromObject(const ryml::ConstNodeRef& object, std::string_view key,
|
||||
std::optional<T> (*from_string_function)(const char* str))
|
||||
{
|
||||
std::optional<T> ret;
|
||||
|
||||
const ryml::ConstNodeRef member = object.find_child(to_csubstr(key));
|
||||
if (member.valid())
|
||||
{
|
||||
const c4::csubstr val = member.val();
|
||||
if (!val.empty())
|
||||
{
|
||||
ret = from_string_function(TinyString(to_stringview(val)));
|
||||
if (!ret.has_value())
|
||||
Log_ErrorFmt("Unknown value for {}: {}", key, to_stringview(val));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log_ErrorFmt("Unexpected empty value in {}", key);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void GameDatabase::EnsureLoaded()
|
||||
{
|
||||
if (s_loaded)
|
||||
|
@ -335,6 +360,8 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
|
|||
settings.gpu_pgxp_tolerance = gpu_pgxp_tolerance.value();
|
||||
if (gpu_pgxp_depth_threshold.has_value())
|
||||
settings.SetPGXPDepthClearThreshold(gpu_pgxp_depth_threshold.value());
|
||||
if (gpu_line_detect_mode.has_value())
|
||||
settings.gpu_line_detect_mode = gpu_line_detect_mode.value();
|
||||
|
||||
if (HasTrait(Trait::ForceInterpreter))
|
||||
{
|
||||
|
@ -713,6 +740,7 @@ bool GameDatabase::LoadFromCache()
|
|||
!ReadOptionalFromStream(stream.get(), &entry.gpu_max_run_ahead) ||
|
||||
!ReadOptionalFromStream(stream.get(), &entry.gpu_pgxp_tolerance) ||
|
||||
!ReadOptionalFromStream(stream.get(), &entry.gpu_pgxp_depth_threshold) ||
|
||||
!ReadOptionalFromStream(stream.get(), &entry.gpu_line_detect_mode) ||
|
||||
!stream->ReadSizePrefixedString(&entry.disc_set_name) || !stream->ReadU32(&num_disc_set_serials))
|
||||
{
|
||||
Log_DevPrintf("Cache entry is corrupted.");
|
||||
|
@ -811,6 +839,7 @@ bool GameDatabase::SaveToCache()
|
|||
result = result && WriteOptionalToStream(stream.get(), entry.gpu_max_run_ahead);
|
||||
result = result && WriteOptionalToStream(stream.get(), entry.gpu_pgxp_tolerance);
|
||||
result = result && WriteOptionalToStream(stream.get(), entry.gpu_pgxp_depth_threshold);
|
||||
result = result && WriteOptionalToStream(stream.get(), entry.gpu_line_detect_mode);
|
||||
|
||||
result = result && stream->WriteSizePrefixedString(entry.disc_set_name);
|
||||
result = result && stream->WriteU32(static_cast<u32>(entry.disc_set_serials.size()));
|
||||
|
@ -1019,6 +1048,8 @@ bool GameDatabase::ParseYamlEntry(Entry* entry, const ryml::ConstNodeRef& value)
|
|||
entry->gpu_max_run_ahead = GetOptionalTFromObject<u32>(settings, "gpuMaxRunAhead");
|
||||
entry->gpu_pgxp_tolerance = GetOptionalTFromObject<float>(settings, "gpuPGXPTolerance");
|
||||
entry->gpu_pgxp_depth_threshold = GetOptionalTFromObject<float>(settings, "gpuPGXPDepthThreshold");
|
||||
entry->gpu_line_detect_mode =
|
||||
ParseOptionalTFromObject<GPULineDetectMode>(settings, "gpuLineDetectMode", &Settings::ParseLineDetectModeName);
|
||||
}
|
||||
|
||||
if (const ryml::ConstNodeRef disc_set = value.find_child("discSet"); disc_set.valid() && disc_set.has_children())
|
||||
|
|
|
@ -80,6 +80,7 @@ struct Entry
|
|||
std::optional<u32> gpu_max_run_ahead;
|
||||
std::optional<float> gpu_pgxp_tolerance;
|
||||
std::optional<float> gpu_pgxp_depth_threshold;
|
||||
std::optional<GPULineDetectMode> gpu_line_detect_mode;
|
||||
|
||||
std::string disc_set_name;
|
||||
std::vector<std::string> disc_set_serials;
|
||||
|
|
|
@ -200,6 +200,7 @@ bool GPU_HW::Initialize()
|
|||
m_debanding = g_settings.gpu_debanding;
|
||||
m_scaled_dithering = g_settings.gpu_scaled_dithering;
|
||||
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_clamp_uvs = ShouldClampUVs();
|
||||
m_compute_uv_range = m_clamp_uvs;
|
||||
m_chroma_smoothing = g_settings.gpu_24bit_chroma_smoothing;
|
||||
|
@ -386,6 +387,7 @@ void GPU_HW::UpdateSettings(const Settings& old_settings)
|
|||
m_debanding = g_settings.gpu_debanding;
|
||||
m_scaled_dithering = g_settings.gpu_scaled_dithering;
|
||||
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_clamp_uvs = clamp_uvs;
|
||||
m_compute_uv_range = m_clamp_uvs;
|
||||
m_chroma_smoothing = g_settings.gpu_24bit_chroma_smoothing;
|
||||
|
@ -1410,7 +1412,7 @@ void GPU_HW::ClearDisplay()
|
|||
g_gpu_device->ClearRenderTarget(m_display_private_texture.get(), 0xFF000000u);
|
||||
}
|
||||
|
||||
void GPU_HW::HandleFlippedQuadTextureCoordinates(BatchVertex* vertices)
|
||||
ALWAYS_INLINE_RELEASE void GPU_HW::HandleFlippedQuadTextureCoordinates(BatchVertex* vertices)
|
||||
{
|
||||
// Taken from beetle-psx gpu_polygon.cpp
|
||||
// For X/Y flipped 2D sprites, PSX games rely on a very specific rasterization behavior. If U or V is decreasing in X
|
||||
|
@ -1433,6 +1435,24 @@ void GPU_HW::HandleFlippedQuadTextureCoordinates(BatchVertex* vertices)
|
|||
const float cax = vertices[0].x - vertices[2].x;
|
||||
const float cay = vertices[0].y - vertices[2].y;
|
||||
|
||||
// Hack for Wild Arms 2: The player sprite is drawn one line at a time with a quad, but the bottom V coordinates
|
||||
// are set to a large distance from the top V coordinate. When upscaling, this means that the coordinate is
|
||||
// interpolated between these two values, result in out-of-bounds sampling. At native, it's fine, because at the
|
||||
// top of the primitive, no amount is added to the coordinates. So, in this case, just set all coordinates to the
|
||||
// same value, from the first vertex, ensuring no interpolation occurs. Gate it based on the Y distance being one
|
||||
// pixel, limiting the risk of false positives.
|
||||
if (m_line_detect_mode == GPULineDetectMode::Quads &&
|
||||
(std::max(vertices[0].y, std::max(vertices[1].y, std::max(vertices[2].y, vertices[3].y))) -
|
||||
std::min(vertices[0].y, std::min(vertices[1].y, std::min(vertices[2].y, vertices[3].y)))) == 1.0f) [[unlikely]]
|
||||
{
|
||||
GL_INS_FMT("HLineQuad detected at [{},{}={},{} {},{}={},{} {},{}={},{} {},{}={},{}", vertices[0].x, vertices[0].y,
|
||||
vertices[0].u, vertices[0].v, vertices[1].x, vertices[1].y, vertices[1].u, vertices[1].v, vertices[2].x,
|
||||
vertices[2].y, vertices[2].u, vertices[2].v, vertices[3].x, vertices[3].y, vertices[3].u, vertices[3].v);
|
||||
vertices[1].v = vertices[0].v;
|
||||
vertices[2].v = vertices[0].v;
|
||||
vertices[3].v = vertices[0].v;
|
||||
}
|
||||
|
||||
// Compute static derivatives, just assume W is uniform across the primitive and that the plane equation remains the
|
||||
// same across the quad. (which it is, there is no Z.. yet).
|
||||
const float dudx = -aby * static_cast<float>(vertices[2].u) - bcy * static_cast<float>(vertices[0].u) -
|
||||
|
@ -1449,11 +1469,8 @@ void GPU_HW::HandleFlippedQuadTextureCoordinates(BatchVertex* vertices)
|
|||
const s32 texArea = (vertices[1].u - vertices[0].u) * (vertices[2].v - vertices[0].v) -
|
||||
(vertices[2].u - vertices[0].u) * (vertices[1].v - vertices[0].v);
|
||||
|
||||
// Leverage PGXP to further avoid 3D polygons that just happen to align this way after projection
|
||||
const bool is_3d = (vertices[0].w != vertices[1].w || vertices[0].w != vertices[2].w);
|
||||
|
||||
// Shouldn't matter as degenerate primitives will be culled anyways.
|
||||
if (area == 0.0f || texArea == 0 || is_3d)
|
||||
if (area == 0.0f || texArea == 0)
|
||||
return;
|
||||
|
||||
// Use floats here as it'll be faster than integer divides.
|
||||
|
@ -1500,6 +1517,156 @@ void GPU_HW::HandleFlippedQuadTextureCoordinates(BatchVertex* vertices)
|
|||
}
|
||||
}
|
||||
|
||||
ALWAYS_INLINE_RELEASE void GPU_HW::ExpandLineTriangles(BatchVertex* vertices, u32 base_vertex)
|
||||
{
|
||||
// Line expansion inspired by beetle-psx.
|
||||
BatchVertex *vshort, *vlong;
|
||||
bool vertical, horizontal;
|
||||
|
||||
if (m_line_detect_mode == GPULineDetectMode::BasicTriangles)
|
||||
{
|
||||
// Given a tall/one-pixel-wide triangle, determine which vertex is the corner with axis-aligned edges.
|
||||
BatchVertex* vcorner;
|
||||
if (vertices[0].u == vertices[1].u && vertices[0].v == vertices[1].v)
|
||||
{
|
||||
// A,B,C
|
||||
vcorner = &vertices[0];
|
||||
vshort = &vertices[1];
|
||||
vlong = &vertices[2];
|
||||
}
|
||||
else if (vertices[1].u == vertices[2].u && vertices[1].v == vertices[2].v)
|
||||
{
|
||||
// B,C,A
|
||||
vcorner = &vertices[1];
|
||||
vshort = &vertices[2];
|
||||
vlong = &vertices[0];
|
||||
}
|
||||
else if (vertices[2].u == vertices[0].u && vertices[2].v == vertices[0].v)
|
||||
{
|
||||
// C,A,B
|
||||
vcorner = &vertices[2];
|
||||
vshort = &vertices[0];
|
||||
vlong = &vertices[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine line direction. Vertical lines will have a width of 1, horizontal lines a height of 1.
|
||||
vertical = ((vcorner->y == vshort->y) && (std::abs(vcorner->x - vshort->x) == 1.0f));
|
||||
horizontal = ((vcorner->x == vshort->x) && (std::abs(vcorner->y - vshort->y) == 1.0f));
|
||||
if (vertical)
|
||||
{
|
||||
// Line should be vertical. Make sure the triangle is actually a right angle.
|
||||
if (vshort->x == vlong->x)
|
||||
std::swap(vshort, vcorner);
|
||||
else if (vcorner->x != vlong->x)
|
||||
return;
|
||||
|
||||
GL_INS_FMT("Vertical line from Y={} to {}", vcorner->y, vlong->y);
|
||||
}
|
||||
else if (horizontal)
|
||||
{
|
||||
// Line should be horizontal. Make sure the triangle is actually a right angle.
|
||||
if (vshort->y == vlong->y)
|
||||
std::swap(vshort, vcorner);
|
||||
else if (vcorner->y != vlong->y)
|
||||
return;
|
||||
|
||||
GL_INS_FMT("Horizontal line from X={} to {}", vcorner->x, vlong->x);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a line-like triangle.
|
||||
return;
|
||||
}
|
||||
|
||||
// We could adjust the short texture coordinate to +1 from its original position, rather than leaving it the same.
|
||||
// However, since the texture is unlikely to be a higher resolution than the one-wide triangle, there would be no
|
||||
// benefit in doing so.
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugAssert(m_line_detect_mode == GPULineDetectMode::AggressiveTriangles);
|
||||
|
||||
// Find direction of line based on horizontal position.
|
||||
BatchVertex *va, *vb, *vc;
|
||||
if (vertices[0].x == vertices[1].x)
|
||||
{
|
||||
va = &vertices[0];
|
||||
vb = &vertices[1];
|
||||
vc = &vertices[2];
|
||||
}
|
||||
else if (vertices[1].x == vertices[2].x)
|
||||
{
|
||||
va = &vertices[1];
|
||||
vb = &vertices[2];
|
||||
vc = &vertices[0];
|
||||
}
|
||||
else if (vertices[2].x == vertices[0].x)
|
||||
{
|
||||
va = &vertices[2];
|
||||
vb = &vertices[0];
|
||||
vc = &vertices[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine line direction. Vertical lines will have a width of 1, horizontal lines a height of 1.
|
||||
vertical = (std::abs(va->x - vc->x) == 1.0f);
|
||||
horizontal = (std::abs(va->y - vb->y) == 1.0f);
|
||||
if (!vertical && !horizontal)
|
||||
return;
|
||||
|
||||
// Determine which vertex is the right angle, based on the vertical position.
|
||||
const BatchVertex* vcorner;
|
||||
if (va->y == vc->y)
|
||||
vcorner = va;
|
||||
else if (vb->y == vc->y)
|
||||
vcorner = vb;
|
||||
else
|
||||
return;
|
||||
|
||||
// Find short/long edge of the triangle.
|
||||
BatchVertex* vother = ((vcorner == va) ? vb : va);
|
||||
vshort = horizontal ? vother : vc;
|
||||
vlong = vertical ? vother : vc;
|
||||
|
||||
// Dark Forces draws its gun sprite vertically, but rotated compared to the sprite date in VRAM.
|
||||
// Therefore the difference in V should be ignored.
|
||||
vshort->u = vcorner->u;
|
||||
vshort->v = vcorner->v;
|
||||
|
||||
// We need to re-compute the UV limits, since we adjusted them above.
|
||||
if (m_compute_uv_range)
|
||||
ComputePolygonUVLimits(vertices[0].texpage, vertices, 3);
|
||||
|
||||
// This is super jank, but because we rewrote the UVs on one of the vertices above, we need to rewrite it to GPU
|
||||
// memory again. Has to be all of them as well, not just vshort, because the UV limits may have changed.
|
||||
DebugAssert(m_batch_vertex_count >= 3);
|
||||
std::memcpy(m_batch_vertex_ptr - 3, vertices, sizeof(BatchVertex) * 3);
|
||||
}
|
||||
|
||||
// Need to write the 4th vertex to the GPU.
|
||||
DebugAssert(m_batch_vertex_space >= 1);
|
||||
BatchVertex* last = &(*(m_batch_vertex_ptr++) = *vlong);
|
||||
last->x = vertical ? vshort->x : vlong->x;
|
||||
last->y = horizontal ? vshort->y : vlong->y;
|
||||
m_batch_vertex_count++;
|
||||
m_batch_vertex_space--;
|
||||
|
||||
// Generate indices for second triangle.
|
||||
DebugAssert(m_batch_index_space >= 3);
|
||||
*(m_batch_index_ptr++) = Truncate16(base_vertex + (vshort - vertices));
|
||||
*(m_batch_index_ptr++) = Truncate16(base_vertex + (vlong - vertices));
|
||||
*(m_batch_index_ptr++) = Truncate16(base_vertex + 3);
|
||||
m_batch_index_count += 3;
|
||||
m_batch_index_space -= 3;
|
||||
}
|
||||
|
||||
void GPU_HW::ComputePolygonUVLimits(u32 texpage, BatchVertex* vertices, u32 num_vertices)
|
||||
{
|
||||
u32 min_u = vertices[0].u, max_u = vertices[0].u, min_v = vertices[0].v, max_v = vertices[0].v;
|
||||
|
@ -1727,7 +1894,9 @@ void GPU_HW::LoadVertices()
|
|||
}
|
||||
}
|
||||
|
||||
if (rc.quad_polygon && m_resolution_scale > 1)
|
||||
// Use PGXP to exclude primitives that are definitely 3D.
|
||||
const bool is_3d = (vertices[0].w != vertices[1].w || vertices[0].w != vertices[2].w);
|
||||
if (m_resolution_scale > 1 && !is_3d && rc.quad_polygon)
|
||||
HandleFlippedQuadTextureCoordinates(vertices.data());
|
||||
|
||||
if (m_compute_uv_range && textured)
|
||||
|
@ -1761,8 +1930,9 @@ void GPU_HW::LoadVertices()
|
|||
const s32 max_x = std::max(max_x_12, native_vertex_positions[0][0]);
|
||||
const s32 min_y = std::min(min_y_12, native_vertex_positions[0][1]);
|
||||
const s32 max_y = std::max(max_y_12, native_vertex_positions[0][1]);
|
||||
const bool first_tri_culled = ((max_x - min_x) >= MAX_PRIMITIVE_WIDTH || (max_y - min_y) >= MAX_PRIMITIVE_HEIGHT);
|
||||
|
||||
if ((max_x - min_x) >= MAX_PRIMITIVE_WIDTH || (max_y - min_y) >= MAX_PRIMITIVE_HEIGHT)
|
||||
if (first_tri_culled)
|
||||
{
|
||||
Log_DebugFmt("Culling too-large polygon: {},{} {},{} {},{}", native_vertex_positions[0][0],
|
||||
native_vertex_positions[0][1], native_vertex_positions[1][0], native_vertex_positions[1][1],
|
||||
|
@ -1828,6 +1998,12 @@ void GPU_HW::LoadVertices()
|
|||
m_batch_index_space -= 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Expand lines to triangles (Doom, Soul Blade, etc.)
|
||||
if (m_line_detect_mode >= GPULineDetectMode::BasicTriangles && !is_3d && !first_tri_culled)
|
||||
ExpandLineTriangles(vertices.data(), start_index);
|
||||
}
|
||||
|
||||
if (m_sw_renderer)
|
||||
{
|
||||
|
|
|
@ -189,7 +189,8 @@ private:
|
|||
void DrawLine(float x0, float y0, u32 col0, float x1, float y1, u32 col1, float depth);
|
||||
|
||||
/// Handles quads with flipped texture coordinate directions.
|
||||
static void HandleFlippedQuadTextureCoordinates(BatchVertex* vertices);
|
||||
void HandleFlippedQuadTextureCoordinates(BatchVertex* vertices);
|
||||
void ExpandLineTriangles(BatchVertex* vertices, u32 base_vertex);
|
||||
|
||||
/// Computes polygon U/V boundaries.
|
||||
void ComputePolygonUVLimits(u32 texpage, BatchVertex* vertices, u32 num_vertices);
|
||||
|
@ -240,6 +241,7 @@ private:
|
|||
bool m_disable_color_perspective : 1 = false;
|
||||
|
||||
GPUTextureFilter m_texture_filtering = GPUTextureFilter::Nearest;
|
||||
GPULineDetectMode m_line_detect_mode = GPULineDetectMode::Disabled;
|
||||
GPUDownsampleMode m_downsample_mode = GPUDownsampleMode::Disabled;
|
||||
GPUWireframeMode m_wireframe_mode = GPUWireframeMode::Disabled;
|
||||
bool m_true_color : 1 = true;
|
||||
|
|
|
@ -196,6 +196,10 @@ void Settings::Load(SettingsInterface& si)
|
|||
ParseTextureFilterName(
|
||||
si.GetStringValue("GPU", "TextureFilter", GetTextureFilterName(DEFAULT_GPU_TEXTURE_FILTER)).c_str())
|
||||
.value_or(DEFAULT_GPU_TEXTURE_FILTER);
|
||||
gpu_line_detect_mode =
|
||||
ParseLineDetectModeName(
|
||||
si.GetStringValue("GPU", "LineDetectMode", GetLineDetectModeName(DEFAULT_GPU_LINE_DETECT_MODE)).c_str())
|
||||
.value_or(DEFAULT_GPU_LINE_DETECT_MODE);
|
||||
gpu_downsample_mode =
|
||||
ParseDownsampleModeName(
|
||||
si.GetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(DEFAULT_GPU_DOWNSAMPLE_MODE)).c_str())
|
||||
|
@ -461,6 +465,7 @@ void Settings::Save(SettingsInterface& si) const
|
|||
si.SetBoolValue("GPU", "Debanding", gpu_debanding);
|
||||
si.SetBoolValue("GPU", "ScaledDithering", gpu_scaled_dithering);
|
||||
si.SetStringValue("GPU", "TextureFilter", GetTextureFilterName(gpu_texture_filter));
|
||||
si.SetStringValue("GPU", "LineDetectMode", GetLineDetectModeName(gpu_line_detect_mode));
|
||||
si.SetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(gpu_downsample_mode));
|
||||
si.SetUIntValue("GPU", "DownsampleScale", gpu_downsample_scale);
|
||||
si.SetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(gpu_wireframe_mode));
|
||||
|
@ -621,6 +626,7 @@ void Settings::FixIncompatibleSettings(bool display_osd_messages)
|
|||
g_settings.gpu_debanding = false;
|
||||
g_settings.gpu_scaled_dithering = false;
|
||||
g_settings.gpu_texture_filter = GPUTextureFilter::Nearest;
|
||||
g_settings.gpu_line_detect_mode = GPULineDetectMode::Disabled;
|
||||
g_settings.gpu_disable_interlacing = false;
|
||||
g_settings.gpu_force_ntsc_timings = false;
|
||||
g_settings.gpu_widescreen_hack = false;
|
||||
|
@ -1005,8 +1011,9 @@ RenderAPI Settings::GetRenderAPIForRenderer(GPURenderer renderer)
|
|||
}
|
||||
}
|
||||
|
||||
static constexpr const std::array s_texture_filter_names = {"Nearest", "Bilinear", "BilinearBinAlpha", "JINC2",
|
||||
"JINC2BinAlpha", "xBR", "xBRBinAlpha"};
|
||||
static constexpr const std::array s_texture_filter_names = {
|
||||
"Nearest", "Bilinear", "BilinearBinAlpha", "JINC2", "JINC2BinAlpha", "xBR", "xBRBinAlpha",
|
||||
};
|
||||
static constexpr const std::array s_texture_filter_display_names = {
|
||||
TRANSLATE_NOOP("GPUTextureFilter", "Nearest-Neighbor"),
|
||||
TRANSLATE_NOOP("GPUTextureFilter", "Bilinear"),
|
||||
|
@ -1014,7 +1021,8 @@ static constexpr const std::array s_texture_filter_display_names = {
|
|||
TRANSLATE_NOOP("GPUTextureFilter", "JINC2 (Slow)"),
|
||||
TRANSLATE_NOOP("GPUTextureFilter", "JINC2 (Slow, No Edge Blending)"),
|
||||
TRANSLATE_NOOP("GPUTextureFilter", "xBR (Very Slow)"),
|
||||
TRANSLATE_NOOP("GPUTextureFilter", "xBR (Very Slow, No Edge Blending)")};
|
||||
TRANSLATE_NOOP("GPUTextureFilter", "xBR (Very Slow, No Edge Blending)"),
|
||||
};
|
||||
|
||||
std::optional<GPUTextureFilter> Settings::ParseTextureFilterName(const char* str)
|
||||
{
|
||||
|
@ -1032,7 +1040,7 @@ std::optional<GPUTextureFilter> Settings::ParseTextureFilterName(const char* str
|
|||
|
||||
const char* Settings::GetTextureFilterName(GPUTextureFilter filter)
|
||||
{
|
||||
return s_texture_filter_names[static_cast<int>(filter)];
|
||||
return s_texture_filter_names[static_cast<size_t>(filter)];
|
||||
}
|
||||
|
||||
const char* Settings::GetTextureFilterDisplayName(GPUTextureFilter filter)
|
||||
|
@ -1040,6 +1048,43 @@ const char* Settings::GetTextureFilterDisplayName(GPUTextureFilter filter)
|
|||
return Host::TranslateToCString("GPUTextureFilter", s_texture_filter_display_names[static_cast<int>(filter)]);
|
||||
}
|
||||
|
||||
static constexpr const std::array s_line_detect_mode_names = {
|
||||
"Disabled",
|
||||
"Quads",
|
||||
"BasicTriangles",
|
||||
"AggressiveTriangles",
|
||||
};
|
||||
static constexpr const std::array s_line_detect_mode_detect_names = {
|
||||
TRANSLATE_NOOP("GPULineDetectMode", "Disabled"),
|
||||
TRANSLATE_NOOP("GPULineDetectMode", "Quads"),
|
||||
TRANSLATE_NOOP("GPULineDetectMode", "Triangles (Basic)"),
|
||||
TRANSLATE_NOOP("GPULineDetectMode", "Triangles (Aggressive)"),
|
||||
};
|
||||
|
||||
std::optional<GPULineDetectMode> Settings::ParseLineDetectModeName(const char* str)
|
||||
{
|
||||
int index = 0;
|
||||
for (const char* name : s_line_detect_mode_names)
|
||||
{
|
||||
if (StringUtil::Strcasecmp(name, str) == 0)
|
||||
return static_cast<GPULineDetectMode>(index);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const char* Settings::GetLineDetectModeName(GPULineDetectMode mode)
|
||||
{
|
||||
return s_line_detect_mode_names[static_cast<size_t>(mode)];
|
||||
}
|
||||
|
||||
const char* Settings::GetLineDetectModeDisplayName(GPULineDetectMode mode)
|
||||
{
|
||||
return Host::TranslateToCString("GPULineDetectMode", s_line_detect_mode_detect_names[static_cast<size_t>(mode)]);
|
||||
}
|
||||
|
||||
static constexpr const std::array s_downsample_mode_names = {"Disabled", "Box", "Adaptive"};
|
||||
static constexpr const std::array s_downsample_mode_display_names = {
|
||||
TRANSLATE_NOOP("GPUDownsampleMode", "Disabled"),
|
||||
|
|
|
@ -115,6 +115,7 @@ struct Settings
|
|||
bool gpu_debanding : 1 = false;
|
||||
bool gpu_scaled_dithering : 1 = true;
|
||||
GPUTextureFilter gpu_texture_filter = DEFAULT_GPU_TEXTURE_FILTER;
|
||||
GPULineDetectMode gpu_line_detect_mode = DEFAULT_GPU_LINE_DETECT_MODE;
|
||||
GPUDownsampleMode gpu_downsample_mode = DEFAULT_GPU_DOWNSAMPLE_MODE;
|
||||
u8 gpu_downsample_scale = 1;
|
||||
GPUWireframeMode gpu_wireframe_mode = DEFAULT_GPU_WIREFRAME_MODE;
|
||||
|
@ -378,6 +379,10 @@ struct Settings
|
|||
static const char* GetTextureFilterName(GPUTextureFilter filter);
|
||||
static const char* GetTextureFilterDisplayName(GPUTextureFilter filter);
|
||||
|
||||
static std::optional<GPULineDetectMode> ParseLineDetectModeName(const char* str);
|
||||
static const char* GetLineDetectModeName(GPULineDetectMode filter);
|
||||
static const char* GetLineDetectModeDisplayName(GPULineDetectMode filter);
|
||||
|
||||
static std::optional<GPUDownsampleMode> ParseDownsampleModeName(const char* str);
|
||||
static const char* GetDownsampleModeName(GPUDownsampleMode mode);
|
||||
static const char* GetDownsampleModeDisplayName(GPUDownsampleMode mode);
|
||||
|
@ -428,6 +433,7 @@ struct Settings
|
|||
|
||||
static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::Automatic;
|
||||
static constexpr GPUTextureFilter DEFAULT_GPU_TEXTURE_FILTER = GPUTextureFilter::Nearest;
|
||||
static constexpr GPULineDetectMode DEFAULT_GPU_LINE_DETECT_MODE = GPULineDetectMode::Disabled;
|
||||
static constexpr GPUDownsampleMode DEFAULT_GPU_DOWNSAMPLE_MODE = GPUDownsampleMode::Disabled;
|
||||
static constexpr GPUWireframeMode DEFAULT_GPU_WIREFRAME_MODE = GPUWireframeMode::Disabled;
|
||||
static constexpr ConsoleRegion DEFAULT_CONSOLE_REGION = ConsoleRegion::Auto;
|
||||
|
|
|
@ -3644,6 +3644,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
|||
g_settings.gpu_debanding != old_settings.gpu_debanding ||
|
||||
g_settings.gpu_scaled_dithering != old_settings.gpu_scaled_dithering ||
|
||||
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_disable_interlacing != old_settings.gpu_disable_interlacing ||
|
||||
g_settings.gpu_force_ntsc_timings != old_settings.gpu_force_ntsc_timings ||
|
||||
g_settings.gpu_24bit_chroma_smoothing != old_settings.gpu_24bit_chroma_smoothing ||
|
||||
|
|
|
@ -105,6 +105,15 @@ enum class GPUWireframeMode : u8
|
|||
Count,
|
||||
};
|
||||
|
||||
enum class GPULineDetectMode : u8
|
||||
{
|
||||
Disabled,
|
||||
Quads,
|
||||
BasicTriangles,
|
||||
AggressiveTriangles,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class DisplayCropMode : u8
|
||||
{
|
||||
None,
|
||||
|
|
|
@ -17,6 +17,12 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsWindow* dialog, QWi
|
|||
setupAdditionalUi();
|
||||
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.resolutionScale, "GPU", "ResolutionScale", 1);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.textureFiltering, "GPU", "TextureFilter",
|
||||
&Settings::ParseTextureFilterName, &Settings::GetTextureFilterName,
|
||||
Settings::DEFAULT_GPU_TEXTURE_FILTER);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuLineDetectMode, "GPU", "LineDetectMode",
|
||||
&Settings::ParseLineDetectModeName, &Settings::GetLineDetectModeName,
|
||||
Settings::DEFAULT_GPU_LINE_DETECT_MODE);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuDownsampleMode, "GPU", "DownsampleMode",
|
||||
&Settings::ParseDownsampleModeName, &Settings::GetDownsampleModeName,
|
||||
Settings::DEFAULT_GPU_DOWNSAMPLE_MODE);
|
||||
|
@ -28,9 +34,6 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsWindow* dialog, QWi
|
|||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceNTSCTimings, "GPU", "ForceNTSCTimings", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.force43For24Bit, "Display", "Force4_3For24Bit", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chromaSmoothingFor24Bit, "GPU", "ChromaSmoothing24Bit", false);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.textureFiltering, "GPU", "TextureFilter",
|
||||
&Settings::ParseTextureFilterName, &Settings::GetTextureFilterName,
|
||||
Settings::DEFAULT_GPU_TEXTURE_FILTER);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.widescreenHack, "GPU", "WidescreenHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useSoftwareRendererForReadbacks, "GPU",
|
||||
"UseSoftwareRendererForReadbacks", false);
|
||||
|
@ -105,10 +108,14 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsWindow* dialog, QWi
|
|||
"Only applies to the hardware renderers."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.textureFiltering, tr("Texture Filtering"),
|
||||
QString::fromUtf8(Settings::GetTextureFilterDisplayName(GPUTextureFilter::Nearest)),
|
||||
QString::fromUtf8(Settings::GetTextureFilterDisplayName(Settings::DEFAULT_GPU_TEXTURE_FILTER)),
|
||||
tr("Smooths out the blockiness of magnified textures on 3D object by using filtering. <br>Will have a "
|
||||
"greater effect on higher resolution scales. Only applies to the hardware renderers. <br>The JINC2 and "
|
||||
"especially xBR filtering modes are very demanding, and may not be worth the speed penalty."));
|
||||
dialog->registerWidgetHelp(m_ui.gpuLineDetectMode, tr("Line Detection"),
|
||||
QString::fromUtf8(Settings::GetLineDetectModeName(Settings::DEFAULT_GPU_LINE_DETECT_MODE)),
|
||||
tr("Attempts to detect one pixel high/wide lines that rely on non-upscaled rasterization "
|
||||
"behavior, filling in gaps introduced by upscaling."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.widescreenHack, tr("Widescreen Hack"), tr("Unchecked"),
|
||||
tr("Scales vertex positions in screen-space to a widescreen aspect ratio, essentially "
|
||||
|
@ -190,6 +197,12 @@ void EnhancementSettingsWidget::setupAdditionalUi()
|
|||
QString::fromUtf8(Settings::GetTextureFilterDisplayName(static_cast<GPUTextureFilter>(i))));
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(GPULineDetectMode::Count); i++)
|
||||
{
|
||||
m_ui.gpuLineDetectMode->addItem(
|
||||
QString::fromUtf8(Settings::GetLineDetectModeDisplayName(static_cast<GPULineDetectMode>(i))));
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(GPUDownsampleMode::Count); i++)
|
||||
{
|
||||
m_ui.gpuDownsampleMode->addItem(
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>640</width>
|
||||
<height>452</height>
|
||||
<height>480</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
|
@ -49,14 +49,14 @@
|
|||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="textureFiltering"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Downsampling:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="gpuDownsampleLayout" stretch="1,0">
|
||||
<item>
|
||||
<widget class="QComboBox" name="gpuDownsampleMode"/>
|
||||
|
@ -76,7 +76,7 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<item row="5" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="trueColor">
|
||||
|
@ -122,6 +122,16 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Line Detection:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="gpuLineDetectMode"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
Loading…
Reference in a new issue