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();
|
||||
const bool game_settings = IsEditingGameSettings(bsi);
|
||||
const u32 resolution_scale = GetEffectiveUIntSetting(bsi, "GPU", "ResolutionScale", 1);
|
||||
|
||||
BeginMenuButtons();
|
||||
|
||||
|
@ -4298,43 +4299,46 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
|||
"GPU", "UseSoftwareRendererForReadbacks", false);
|
||||
}
|
||||
|
||||
if (is_hardware)
|
||||
{
|
||||
MenuHeading(FSUI_CSTR("Rendering"));
|
||||
|
||||
DrawIntListSetting(
|
||||
bsi, FSUI_CSTR("Internal 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(
|
||||
bsi, FSUI_CSTR("Texture Filtering"), FSUI_CSTR("Smooths out the blockiness of magnified textures on 3D objects."),
|
||||
"GPU", "TextureFilter", Settings::DEFAULT_GPU_TEXTURE_FILTER, &Settings::ParseTextureFilterName,
|
||||
&Settings::GetTextureFilterName, &Settings::GetTextureFilterDisplayName, GPUTextureFilter::Count, is_hardware);
|
||||
DrawEnumSetting(bsi, FSUI_CSTR("Texture Filtering"),
|
||||
FSUI_CSTR("Smooths out the blockiness of magnified textures on 3D objects."), "GPU",
|
||||
"TextureFilter", Settings::DEFAULT_GPU_TEXTURE_FILTER, &Settings::ParseTextureFilterName,
|
||||
&Settings::GetTextureFilterName, &Settings::GetTextureFilterDisplayName, GPUTextureFilter::Count);
|
||||
|
||||
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);
|
||||
resolution_scale > 1);
|
||||
|
||||
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);
|
||||
"TrueColor", true);
|
||||
|
||||
DrawToggleSetting(
|
||||
bsi, FSUI_CSTR("True Color Debanding"),
|
||||
FSUI_CSTR("Applies modern dithering techniques to further smooth out gradients when true color is enabled."), "GPU",
|
||||
"Debanding", false, is_hardware && bsi->GetBoolValue("GPU", "TrueColor", false));
|
||||
FSUI_CSTR("Applies modern dithering techniques to further smooth out gradients when true color is enabled."),
|
||||
"GPU", "Debanding", false, bsi->GetBoolValue("GPU", "TrueColor", false));
|
||||
|
||||
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."),
|
||||
"GPU", "WidescreenHack", false, is_hardware);
|
||||
"GPU", "WidescreenHack", false);
|
||||
|
||||
DrawToggleSetting(
|
||||
bsi, FSUI_CSTR("PGXP Geometry Correction"),
|
||||
FSUI_CSTR("Reduces \"wobbly\" polygons by attempting to preserve the fractional component through memory "
|
||||
"transfers."),
|
||||
"GPU", "PGXPEnable", false);
|
||||
}
|
||||
|
||||
MenuHeading(FSUI_CSTR("Screen Display"));
|
||||
|
||||
|
@ -4401,12 +4405,6 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
|||
"ScreenshotQuality", Settings::DEFAULT_DISPLAY_SCREENSHOT_QUALITY, 1, 100, "%d%%");
|
||||
|
||||
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(
|
||||
bsi, FSUI_CSTR("Disable Interlacing"),
|
||||
FSUI_CSTR("Disables interlaced rendering and display in the GPU. Some games can render in 480p this way, "
|
||||
|
@ -4421,10 +4419,29 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
|||
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",
|
||||
"Force4_3For24Bit", false);
|
||||
|
||||
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);
|
||||
|
||||
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, 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. Only "
|
||||
"applies to the hardware renderers."),
|
||||
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);
|
||||
|
||||
MenuHeading(FSUI_CSTR("PGXP (Precision Geometry Transform Pipeline)"));
|
||||
|
||||
|
@ -4439,16 +4456,17 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
|||
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("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);
|
||||
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);
|
||||
|
@ -4461,6 +4479,7 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
|||
DrawToggleSetting(bsi, FSUI_CSTR("Preload Replacement Textures"),
|
||||
FSUI_CSTR("Loads all replacement texture to RAM, reducing stuttering at runtime."),
|
||||
"TextureReplacements", "PreloadTextures", false);
|
||||
}
|
||||
|
||||
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 not enabled. Please note that enabling rewind may significantly increase system requirements.");
|
||||
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/Rewind");
|
||||
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", "Skips the presentation/display of frames that are not unique. Can result in worse frame pacing.");
|
||||
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", "Sort By");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Sort Reversed");
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace GameDatabase {
|
|||
enum : u32
|
||||
{
|
||||
GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48,
|
||||
GAME_DATABASE_CACHE_VERSION = 8,
|
||||
GAME_DATABASE_CACHE_VERSION = 9,
|
||||
};
|
||||
|
||||
static Entry* GetMutableEntry(std::string_view serial);
|
||||
|
@ -63,6 +63,7 @@ static constexpr const std::array<const char*, static_cast<u32>(GameDatabase::Tr
|
|||
"ForceInterpreter",
|
||||
"ForceSoftwareRenderer",
|
||||
"ForceSoftwareRendererForReadbacks",
|
||||
"ForceRoundTextureCoordinates",
|
||||
"ForceInterlacing",
|
||||
"DisableTrueColor",
|
||||
"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 Software Renderer"),
|
||||
TRANSLATE_NOOP("GameDatabase", "Force Software Renderer For Readbacks"),
|
||||
TRANSLATE_NOOP("GameDatabase", "Force Round Texture Coordinates"),
|
||||
TRANSLATE_NOOP("GameDatabase", "Force Interlacing"),
|
||||
TRANSLATE_NOOP("GameDatabase", "Disable True Color"),
|
||||
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;
|
||||
}
|
||||
|
||||
if (HasTrait(Trait::ForceRoundUpscaledTextureCoordinates))
|
||||
{
|
||||
settings.gpu_force_round_texcoords = true;
|
||||
}
|
||||
|
||||
if (HasTrait(Trait::ForceInterlacing))
|
||||
{
|
||||
if (display_osd_messages && settings.gpu_disable_interlacing)
|
||||
|
|
|
@ -31,6 +31,7 @@ enum class Trait : u32
|
|||
ForceInterpreter,
|
||||
ForceSoftwareRenderer,
|
||||
ForceSoftwareRendererForReadbacks,
|
||||
ForceRoundUpscaledTextureCoordinates,
|
||||
ForceInterlacing,
|
||||
DisableTrueColor,
|
||||
DisableUpscaling,
|
||||
|
|
|
@ -198,7 +198,9 @@ bool GPU_HW::Initialize()
|
|||
m_per_sample_shading = g_settings.gpu_per_sample_shading && features.per_sample_shading;
|
||||
m_true_color = g_settings.gpu_true_color;
|
||||
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_line_detect_mode = (m_resolution_scale > 1) ? g_settings.gpu_line_detect_mode : GPULineDetectMode::Disabled;
|
||||
m_clamp_uvs = ShouldClampUVs();
|
||||
|
@ -336,7 +338,10 @@ void GPU_HW::UpdateSettings(const Settings& old_settings)
|
|||
const bool shaders_changed =
|
||||
(m_resolution_scale != resolution_scale || m_multisamples != multisamples ||
|
||||
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_downsample_mode != downsample_mode ||
|
||||
(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_true_color = g_settings.gpu_true_color;
|
||||
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_line_detect_mode = (m_resolution_scale > 1) ? g_settings.gpu_line_detect_mode : GPULineDetectMode::Disabled;
|
||||
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("Dithering: {}{}", m_true_color ? "Disabled" : "Enabled",
|
||||
(!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("Dual-source blending: {}", m_supports_dual_source_blend ? "Supported" : "Not supported");
|
||||
INFO_LOG("Clamping UVs: {}", m_clamp_uvs ? "YES" : "NO");
|
||||
INFO_LOG("Depth buffer: {}", m_pgxp_depth_buffer ? "YES" : "NO");
|
||||
INFO_LOG("Downsampling: {}", Settings::GetDownsampleModeDisplayName(m_downsample_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");
|
||||
}
|
||||
|
||||
|
@ -858,8 +867,9 @@ bool GPU_HW::CompilePipelines()
|
|||
{
|
||||
const std::string fs = shadergen.GenerateBatchFragmentShader(
|
||||
static_cast<BatchRenderMode>(render_mode), static_cast<GPUTransparencyMode>(transparency_mode),
|
||||
static_cast<GPUTextureMode>(texture_mode), m_texture_filtering, ConvertToBoolUnchecked(dithering),
|
||||
ConvertToBoolUnchecked(interlacing), ConvertToBoolUnchecked(check_mask));
|
||||
static_cast<BatchTextureMode>(texture_mode), m_texture_filtering, m_force_round_texcoords,
|
||||
ConvertToBoolUnchecked(dithering), ConvertToBoolUnchecked(interlacing),
|
||||
ConvertToBoolUnchecked(check_mask));
|
||||
|
||||
if (!(batch_fragment_shaders[render_mode][transparency_mode][texture_mode][check_mask][dithering]
|
||||
[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++)
|
||||
{
|
||||
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 =
|
||||
(render_mode == static_cast<u8>(BatchRenderMode::ShaderBlend) &&
|
||||
((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
|
||||
// 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_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};
|
||||
|
||||
GPUTextureMode texture_mode = GPUTextureMode::Disabled;
|
||||
BatchTextureMode texture_mode = BatchTextureMode::Disabled;
|
||||
if (rc.IsTexturingEnabled())
|
||||
{
|
||||
// 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) ?
|
||||
GPUTextureMode::Direct16Bit :
|
||||
m_draw_mode.mode_reg.texture_mode;
|
||||
texture_mode = (m_draw_mode.mode_reg.texture_mode == GPUTextureMode::Reserved_Direct16Bit) ?
|
||||
BatchTextureMode::Direct16Bit :
|
||||
static_cast<BatchTextureMode>(m_draw_mode.mode_reg.texture_mode.GetValue());
|
||||
}
|
||||
|
||||
// has any state changed which requires a new batch?
|
||||
|
@ -3055,7 +3065,7 @@ void GPU_HW::DispatchRenderCommand()
|
|||
// transparency mode change
|
||||
const bool check_mask_before_draw = m_GPUSTAT.check_mask_before_draw;
|
||||
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}};
|
||||
|
||||
|
|
|
@ -33,6 +33,19 @@ public:
|
|||
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() override;
|
||||
|
||||
|
@ -58,7 +71,7 @@ private:
|
|||
MAX_BATCH_VERTEX_COUNTER_IDS = 65536 - 2,
|
||||
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),
|
||||
NUM_TEXTURE_MODES = 4,
|
||||
NUM_TEXTURE_MODES = static_cast<u32>(BatchTextureMode::MaxCount),
|
||||
};
|
||||
enum : u8
|
||||
{
|
||||
|
@ -88,7 +101,7 @@ private:
|
|||
|
||||
struct BatchConfig
|
||||
{
|
||||
GPUTextureMode texture_mode = GPUTextureMode::Disabled;
|
||||
BatchTextureMode texture_mode = BatchTextureMode::Disabled;
|
||||
GPUTransparencyMode transparency_mode = GPUTransparencyMode::Disabled;
|
||||
bool dithering = false;
|
||||
bool interlacing = false;
|
||||
|
@ -235,6 +248,7 @@ private:
|
|||
bool m_per_sample_shading : 1 = false;
|
||||
bool m_scaled_dithering : 1 = false;
|
||||
bool m_disable_color_perspective : 1 = false;
|
||||
bool m_force_round_texcoords = false;
|
||||
|
||||
GPUTextureFilter m_texture_filtering = GPUTextureFilter::Nearest;
|
||||
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,
|
||||
GPUTransparencyMode transparency, GPUTextureMode texture_mode,
|
||||
GPUTextureFilter texture_filtering, bool dithering,
|
||||
bool interlacing, bool check_mask)
|
||||
std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(
|
||||
GPU_HW::BatchRenderMode render_mode, GPUTransparencyMode transparency, GPU_HW::BatchTextureMode texture_mode,
|
||||
GPUTextureFilter texture_filtering, bool force_round_texcoords, bool dithering, bool interlacing, bool check_mask)
|
||||
{
|
||||
// TODO: don't write depth for shader blend
|
||||
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 &&
|
||||
(transparency != GPUTransparencyMode::Disabled || check_mask));
|
||||
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, "TEXTURED", textured);
|
||||
DefineMacro(ss, "PALETTE",
|
||||
texture_mode == GPUTextureMode::Palette4Bit || texture_mode == GPUTextureMode::Palette8Bit);
|
||||
DefineMacro(ss, "PALETTE_4_BIT", texture_mode == GPUTextureMode::Palette4Bit);
|
||||
DefineMacro(ss, "PALETTE_8_BIT", texture_mode == GPUTextureMode::Palette8Bit);
|
||||
texture_mode == GPU_HW::BatchTextureMode::Palette4Bit ||
|
||||
texture_mode == GPU_HW::BatchTextureMode::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_SCALED", m_scaled_dithering);
|
||||
// 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, "USE_DUAL_SOURCE", use_dual_source);
|
||||
DefineMacro(ss, "WRITE_MASK_AS_DEPTH", m_write_mask_as_depth);
|
||||
DefineMacro(ss, "FORCE_ROUND_TEXCOORDS", force_round_texcoords);
|
||||
|
||||
WriteCommonFunctions(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.
|
||||
// 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)
|
||||
|
|
|
@ -16,8 +16,9 @@ public:
|
|||
|
||||
std::string GenerateBatchVertexShader(bool textured, bool pgxp_depth);
|
||||
std::string GenerateBatchFragmentShader(GPU_HW::BatchRenderMode render_mode, GPUTransparencyMode transparency,
|
||||
GPUTextureMode texture_mode, GPUTextureFilter texture_filtering,
|
||||
bool dithering, bool interlacing, bool check_mask);
|
||||
GPU_HW::BatchTextureMode texture_mode, GPUTextureFilter texture_filtering,
|
||||
bool force_round_texcoords, bool dithering, bool interlacing,
|
||||
bool check_mask);
|
||||
std::string GenerateWireframeGeometryShader();
|
||||
std::string GenerateWireframeFragmentShader();
|
||||
std::string GenerateVRAMReadFragmentShader();
|
||||
|
|
|
@ -53,8 +53,7 @@ enum class GPUTextureMode : u8
|
|||
Palette4Bit = 0,
|
||||
Palette8Bit = 1,
|
||||
Direct16Bit = 2,
|
||||
Reserved_Direct16Bit2 = 3, // Not used.
|
||||
Disabled = 3 // Not a register value
|
||||
Reserved_Direct16Bit = 3, // Not used.
|
||||
};
|
||||
|
||||
IMPLEMENT_ENUM_CLASS_BITWISE_OPERATORS(GPUTextureMode);
|
||||
|
|
|
@ -197,6 +197,7 @@ void Settings::Load(SettingsInterface& si)
|
|||
gpu_true_color = si.GetBoolValue("GPU", "TrueColor", true);
|
||||
gpu_debanding = si.GetBoolValue("GPU", "Debanding", false);
|
||||
gpu_scaled_dithering = si.GetBoolValue("GPU", "ScaledDithering", true);
|
||||
gpu_force_round_texcoords = si.GetBoolValue("GPU", "ForceRoundTextureCoordinates", false);
|
||||
gpu_texture_filter =
|
||||
ParseTextureFilterName(
|
||||
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", "Debanding", gpu_debanding);
|
||||
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", "LineDetectMode", GetLineDetectModeName(gpu_line_detect_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_debanding = false;
|
||||
g_settings.gpu_scaled_dithering = false;
|
||||
g_settings.gpu_force_round_texcoords = false;
|
||||
g_settings.gpu_texture_filter = GPUTextureFilter::Nearest;
|
||||
g_settings.gpu_line_detect_mode = GPULineDetectMode::Disabled;
|
||||
g_settings.gpu_disable_interlacing = false;
|
||||
|
|
|
@ -117,6 +117,7 @@ struct Settings
|
|||
bool gpu_true_color : 1 = true;
|
||||
bool gpu_debanding : 1 = false;
|
||||
bool gpu_scaled_dithering : 1 = true;
|
||||
bool gpu_force_round_texcoords : 1 = false;
|
||||
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;
|
||||
|
|
|
@ -4015,6 +4015,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
|||
g_settings.gpu_true_color != old_settings.gpu_true_color ||
|
||||
g_settings.gpu_debanding != old_settings.gpu_debanding ||
|
||||
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_line_detect_mode != old_settings.gpu_line_detect_mode ||
|
||||
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,
|
||||
&GraphicsSettingsWidget::onAdapterChanged);
|
||||
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,
|
||||
&GraphicsSettingsWidget::onAspectRatioChanged);
|
||||
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.useSoftwareRendererForReadbacks, "GPU",
|
||||
"UseSoftwareRendererForReadbacks", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceRoundedTexcoords, "GPU", "ForceRoundTextureCoordinates",
|
||||
false);
|
||||
|
||||
connect(m_ui.fullscreenMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&GraphicsSettingsWidget::onFullscreenModeChanged);
|
||||
|
@ -230,7 +234,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
|||
updateRendererDependentOptions();
|
||||
onAspectRatioChanged();
|
||||
onDownsampleModeChanged();
|
||||
onTrueColorChanged();
|
||||
updateResolutionDependentOptions();
|
||||
onEnableAnyTextureReplacementsChanged();
|
||||
onEnableVRAMWriteDumpingChanged();
|
||||
onShowDebugSettingsChanged(QtHost::ShouldShowDebugOptions());
|
||||
|
@ -373,6 +377,10 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
|||
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 "
|
||||
"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
|
||||
|
||||
|
@ -796,6 +804,20 @@ void GraphicsSettingsWidget::onAspectRatioChanged()
|
|||
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()
|
||||
{
|
||||
const int index = m_ui.msaaMode->currentIndex();
|
||||
|
@ -816,8 +838,8 @@ void GraphicsSettingsWidget::onMSAAModeChanged()
|
|||
|
||||
void GraphicsSettingsWidget::onTrueColorChanged()
|
||||
{
|
||||
const int resolution_scale = m_ui.resolutionScale->currentIndex();
|
||||
const bool true_color = m_ui.trueColor->isChecked();
|
||||
const int resolution_scale = m_dialog->getEffectiveIntValue("GPU", "ResolutionScale", 1);
|
||||
const bool true_color = m_dialog->getEffectiveBoolValue("GPU", "TrueColor", false);
|
||||
const bool allow_scaled_dithering = (resolution_scale != 1 && !true_color);
|
||||
const bool allow_debanding = true_color;
|
||||
m_ui.scaledDithering->setEnabled(allow_scaled_dithering);
|
||||
|
|
|
@ -29,6 +29,7 @@ private Q_SLOTS:
|
|||
|
||||
void onAdapterChanged();
|
||||
void onAspectRatioChanged();
|
||||
void updateResolutionDependentOptions();
|
||||
void onMSAAModeChanged();
|
||||
void onTrueColorChanged();
|
||||
void onDownsampleModeChanged();
|
||||
|
|
|
@ -468,10 +468,10 @@
|
|||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="debanding">
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="gpuThread">
|
||||
<property name="text">
|
||||
<string>True Color Debanding</string>
|
||||
<string>Threaded Rendering</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -489,10 +489,17 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="gpuThread">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="debanding">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
Loading…
Reference in a new issue