mirror of
https://github.com/libretro/pcsx2.git
synced 2024-11-27 19:30:36 +00:00
GS/HW: Relax CPU sprite render requirements further via levels
This commit is contained in:
parent
70c1620a87
commit
ebeb646e4d
@ -186,16 +186,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
sif, m_ui.blending, "EmuCore/GS", "accurate_blending_unit", static_cast<int>(AccBlendLevel::Basic));
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(
|
||||
sif, m_ui.texturePreloading, "EmuCore/GS", "texture_preloading", static_cast<int>(TexturePreloadingLevel::Off));
|
||||
|
||||
connect(m_ui.trilinearFiltering, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&GraphicsSettingsWidget::onTrilinearFilteringChanged);
|
||||
connect(m_ui.gpuPaletteConversion, QOverload<int>::of(&QCheckBox::stateChanged), this,
|
||||
&GraphicsSettingsWidget::onGpuPaletteConversionChanged);
|
||||
connect(m_ui.textureInsideRt, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&GraphicsSettingsWidget::onTextureInsideRtChanged);
|
||||
onTrilinearFilteringChanged();
|
||||
onGpuPaletteConversionChanged(m_ui.gpuPaletteConversion->checkState());
|
||||
onTextureInsideRtChanged();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HW Renderer Fixes
|
||||
@ -203,6 +196,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.crcFixLevel, "EmuCore/GS", "crc_hack_level", static_cast<int>(CRCHackLevel::Automatic), -1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfScreenFix, "EmuCore/GS", "UserHacks_Half_Bottom_Override", -1, -1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cpuSpriteRenderBW, "EmuCore/GS", "UserHacks_CPUSpriteRenderBW", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cpuSpriteRenderLevel, "EmuCore/GS", "UserHacks_CPUSpriteRenderLevel", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cpuCLUTRender, "EmuCore/GS", "UserHacks_CPUCLUTRender", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.gpuTargetCLUTMode, "EmuCore/GS", "UserHacks_GPUTargetCLUTMode", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawStart, "EmuCore/GS", "UserHacks_SkipDraw_Start", 0);
|
||||
@ -220,6 +214,15 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.targetPartialInvalidation, "EmuCore/GS", "UserHacks_TargetPartialInvalidation", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.estimateTextureRegion, "EmuCore/GS", "UserHacks_EstimateTextureRegion", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.gpuPaletteConversion, "EmuCore/GS", "paltex", false);
|
||||
connect(m_ui.cpuSpriteRenderBW, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&GraphicsSettingsWidget::onCPUSpriteRenderBWChanged);
|
||||
connect(m_ui.textureInsideRt, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&GraphicsSettingsWidget::onTextureInsideRtChanged);
|
||||
connect(m_ui.gpuPaletteConversion, QOverload<int>::of(&QCheckBox::stateChanged), this,
|
||||
&GraphicsSettingsWidget::onGpuPaletteConversionChanged);
|
||||
onCPUSpriteRenderBWChanged();
|
||||
onTextureInsideRtChanged();
|
||||
onGpuPaletteConversionChanged(m_ui.gpuPaletteConversion->checkState());
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HW Upscaling Fixes
|
||||
@ -889,6 +892,12 @@ void GraphicsSettingsWidget::onGpuPaletteConversionChanged(int state)
|
||||
m_ui.anisotropicFiltering->setDisabled(disabled);
|
||||
}
|
||||
|
||||
void GraphicsSettingsWidget::onCPUSpriteRenderBWChanged()
|
||||
{
|
||||
const int value = m_dialog->getEffectiveIntValue("EmuCore/GS", "UserHacks_CPUSpriteRenderBW", 0);
|
||||
m_ui.cpuSpriteRenderLevel->setEnabled(value != 0);
|
||||
}
|
||||
|
||||
void GraphicsSettingsWidget::onTextureInsideRtChanged()
|
||||
{
|
||||
const bool disabled = static_cast<GSTextureInRtMode>(m_ui.textureInsideRt->currentIndex()) >= GSTextureInRtMode::InsideTargets;
|
||||
|
@ -41,6 +41,7 @@ private Q_SLOTS:
|
||||
void onAdapterChanged(int index);
|
||||
void onTrilinearFilteringChanged();
|
||||
void onGpuPaletteConversionChanged(int state);
|
||||
void onCPUSpriteRenderBWChanged();
|
||||
void onTextureInsideRtChanged();
|
||||
void onFullscreenModeChanged(int index);
|
||||
void onShadeBoostChanged();
|
||||
|
@ -813,65 +813,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="cpuSpriteRenderBW">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>0 (Disabled)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1 (64 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2 (128 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>3 (192 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4 (256 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>5 (320 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>6 (384 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>7 (448 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>8 (512 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>9 (576 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>10 (640 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
@ -1096,6 +1037,88 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,0">
|
||||
<item>
|
||||
<widget class="QComboBox" name="cpuSpriteRenderBW">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>0 (Disabled)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1 (64 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2 (128 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>3 (192 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4 (256 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>5 (320 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>6 (384 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>7 (448 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>8 (512 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>9 (576 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>10 (640 Max Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cpuSpriteRenderLevel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Sprites Only</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Sprites/Triangles</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Blended Sprites/Triangles</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="upscalingFixesTab">
|
||||
|
@ -753,7 +753,8 @@ struct Pcsx2Config
|
||||
int UserHacks_TCOffsetX{0};
|
||||
int UserHacks_TCOffsetY{0};
|
||||
int UserHacks_CPUSpriteRenderBW{0};
|
||||
int UserHacks_CPUCLUTRender{ 0 };
|
||||
int UserHacks_CPUSpriteRenderLevel{0};
|
||||
int UserHacks_CPUCLUTRender{0};
|
||||
GSGPUTargetCLUTMode UserHacks_GPUTargetCLUTMode{GSGPUTargetCLUTMode::Disabled};
|
||||
GSTextureInRtMode UserHacks_TextureInsideRt{GSTextureInRtMode::Disabled};
|
||||
TriFiltering TriFilter{TriFiltering::Automatic};
|
||||
|
@ -241,6 +241,11 @@
|
||||
"minimum": 1,
|
||||
"maximum": 10
|
||||
},
|
||||
"cpuSpriteRenderLevel": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 2
|
||||
},
|
||||
"cpuCLUTRender": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
|
@ -3170,6 +3170,8 @@ void FullscreenUI::DrawGraphicsSettingsPage()
|
||||
static constexpr const char* s_cpu_sprite_render_bw_options[] = {"0 (Disabled)", "1 (64 Max Width)", "2 (128 Max Width)",
|
||||
"3 (192 Max Width)", "4 (256 Max Width)", "5 (320 Max Width)", "6 (384 Max Width)", "7 (448 Max Width)",
|
||||
"8 (512 Max Width)", "9 (576 Max Width)", "10 (640 Max Width)"};
|
||||
static constexpr const char* s_cpu_sprite_render_level_options[] = {
|
||||
"Sprites Only", "Sprites/Triangles", "Blended Sprites/Triangles"};
|
||||
static constexpr const char* s_cpu_clut_render_options[] = {"0 (Disabled)", "1 (Normal)", "2 (Aggressive)"};
|
||||
static constexpr const char* s_texture_inside_rt_options[] = {"Disabled", "Inside Target", "Merge Targets"};
|
||||
static constexpr const char* s_half_pixel_offset_options[] = {
|
||||
@ -3182,6 +3184,8 @@ void FullscreenUI::DrawGraphicsSettingsPage()
|
||||
"UserHacks_Half_Bottom_Override", -1, s_generic_options, std::size(s_generic_options), -1);
|
||||
DrawIntListSetting(bsi, "CPU Sprite Render Size", "Uses software renderer to draw texture decompression-like sprites.",
|
||||
"EmuCore/GS", "UserHacks_CPUSpriteRenderBW", 0, s_cpu_sprite_render_bw_options, std::size(s_cpu_sprite_render_bw_options));
|
||||
DrawIntListSetting(bsi, "CPU Sprite Render Level", "Determines filter level for CPU sprite render.", "EmuCore/GS",
|
||||
"UserHacks_CPUSpriteRenderLevel", 0, s_cpu_sprite_render_level_options, std::size(s_cpu_sprite_render_level_options));
|
||||
DrawIntListSetting(bsi, "Software CLUT Render", "Uses software renderer to draw texture CLUT points/sprites.", "EmuCore/GS",
|
||||
"UserHacks_CPUCLUTRender", 0, s_cpu_clut_render_options, std::size(s_cpu_clut_render_options));
|
||||
DrawIntSpinBoxSetting(
|
||||
|
@ -404,7 +404,7 @@ void ImGuiManager::DrawSettingsOverlay()
|
||||
if (GSConfig.UserHacks_TCOffsetX != 0 || GSConfig.UserHacks_TCOffsetY != 0)
|
||||
APPEND("TCO={}/{} ", GSConfig.UserHacks_TCOffsetX, GSConfig.UserHacks_TCOffsetY);
|
||||
if (GSConfig.UserHacks_CPUSpriteRenderBW != 0)
|
||||
APPEND("CSBW={} ", GSConfig.UserHacks_CPUSpriteRenderBW);
|
||||
APPEND("CSBW={}/{} ", GSConfig.UserHacks_CPUSpriteRenderBW, GSConfig.UserHacks_CPUSpriteRenderLevel);
|
||||
if (GSConfig.UserHacks_CPUCLUTRender != 0)
|
||||
APPEND("CCLUT={} ", GSConfig.UserHacks_CPUCLUTRender);
|
||||
if (GSConfig.UserHacks_GPUTargetCLUTMode != GSGPUTargetCLUTMode::Disabled)
|
||||
|
@ -4568,40 +4568,42 @@ GSRendererHW::CLUTDrawTestResult GSRendererHW::PossibleCLUTDrawAggressive()
|
||||
bool GSRendererHW::CanUseSwPrimRender(bool no_rt, bool no_ds, bool draw_sprite_tex)
|
||||
{
|
||||
// Master enable.
|
||||
if (GSConfig.UserHacks_CPUSpriteRenderBW == 0)
|
||||
const int bw = GSConfig.UserHacks_CPUSpriteRenderBW;
|
||||
const int level = GSConfig.UserHacks_CPUSpriteRenderLevel;
|
||||
if (bw == 0)
|
||||
return false;
|
||||
|
||||
// We don't ever want to do this when we have a depth buffer, and only for textured sprites.
|
||||
if (no_rt || !no_ds || !draw_sprite_tex)
|
||||
if (no_rt || !no_ds || (level == 0 && !draw_sprite_tex))
|
||||
return false;
|
||||
|
||||
// Check the size threshold. Spider-man 2 uses a FBW of 32 for some silly reason...
|
||||
if (m_context->FRAME.FBW > static_cast<u32>(GSConfig.UserHacks_CPUSpriteRenderBW) && m_context->FRAME.FBW != 32)
|
||||
if (m_context->FRAME.FBW > static_cast<u32>(bw) && m_context->FRAME.FBW != 32)
|
||||
return false;
|
||||
|
||||
// We shouldn't be using mipmapping, and this shouldn't be a blended draw.
|
||||
// TODO: Jak 3 builds textures semi-procedurally using blending, and would be a good candidate here.
|
||||
if (IsMipMapActive() || !IsOpaque())
|
||||
if (level < 2 && (IsMipMapActive() || !IsOpaque()))
|
||||
return false;
|
||||
|
||||
// Make sure this isn't something we've actually rendered to (e.g. a texture shuffle).
|
||||
// We do this by checking the texture block width against the target's block width, as all the decompression draws
|
||||
// will use a much smaller block size than the framebuffer.
|
||||
GSTextureCache::Target* src_target = m_tc->GetTargetWithSharedBits(m_context->TEX0.TBP0, m_context->TEX0.PSM);
|
||||
if (src_target && src_target->m_TEX0.TBW == m_context->TEX0.TBW)
|
||||
if (PRIM->TME)
|
||||
{
|
||||
// If the EE has written over our sample area, we're fine to do this on the CPU, despite the target.
|
||||
if (!src_target->m_dirty.empty())
|
||||
GSTextureCache::Target* src_target = m_tc->GetTargetWithSharedBits(m_context->TEX0.TBP0, m_context->TEX0.PSM);
|
||||
if (src_target)
|
||||
{
|
||||
const GSVector4i tr(GetTextureMinMax(m_context->TEX0, m_context->CLAMP, m_vt.IsLinear()).coverage);
|
||||
for (GSDirtyRect& rc : src_target->m_dirty)
|
||||
// If the EE has written over our sample area, we're fine to do this on the CPU, despite the target.
|
||||
if (!src_target->m_dirty.empty())
|
||||
{
|
||||
if (!rc.GetDirtyRect(m_context->TEX0).rintersect(tr).rempty())
|
||||
return true;
|
||||
const GSVector4i tr(GetTextureMinMax(m_context->TEX0, m_context->CLAMP, m_vt.IsLinear()).coverage);
|
||||
for (GSDirtyRect& rc : src_target->m_dirty)
|
||||
{
|
||||
if (!rc.GetDirtyRect(m_context->TEX0).rintersect(tr).rempty())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// We can use the sw prim render path!
|
||||
|
@ -366,6 +366,7 @@ static const char* s_gs_hw_fix_names[] = {
|
||||
"texturePreloading",
|
||||
"deinterlace",
|
||||
"cpuSpriteRenderBW",
|
||||
"cpuSpriteRenderLevel",
|
||||
"cpuCLUTRender",
|
||||
"gpuTargetCLUT",
|
||||
"gpuPaletteConversion",
|
||||
@ -631,6 +632,9 @@ bool GameDatabaseSchema::GameEntry::configMatchesHWFix(const Pcsx2Config::GSOpti
|
||||
case GSHWFixId::CPUSpriteRenderBW:
|
||||
return (config.UserHacks_CPUSpriteRenderBW == value);
|
||||
|
||||
case GSHWFixId::CPUSpriteRenderLevel:
|
||||
return (config.UserHacks_CPUSpriteRenderLevel == value);
|
||||
|
||||
case GSHWFixId::CPUCLUTRender:
|
||||
return (config.UserHacks_CPUCLUTRender == value);
|
||||
|
||||
@ -814,6 +818,10 @@ u32 GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
|
||||
config.UserHacks_CPUSpriteRenderBW = value;
|
||||
break;
|
||||
|
||||
case GSHWFixId::CPUSpriteRenderLevel:
|
||||
config.UserHacks_CPUSpriteRenderLevel = value;
|
||||
break;
|
||||
|
||||
case GSHWFixId::CPUCLUTRender:
|
||||
config.UserHacks_CPUCLUTRender = value;
|
||||
break;
|
||||
|
@ -87,6 +87,7 @@ namespace GameDatabaseSchema
|
||||
TexturePreloading,
|
||||
Deinterlace,
|
||||
CPUSpriteRenderBW,
|
||||
CPUSpriteRenderLevel,
|
||||
CPUCLUTRender,
|
||||
GPUTargetCLUT,
|
||||
GPUPaletteConversion,
|
||||
|
@ -524,6 +524,7 @@ bool Pcsx2Config::GSOptions::OptionsAreEqual(const GSOptions& right) const
|
||||
OpEqu(UserHacks_TCOffsetX) &&
|
||||
OpEqu(UserHacks_TCOffsetY) &&
|
||||
OpEqu(UserHacks_CPUSpriteRenderBW) &&
|
||||
OpEqu(UserHacks_CPUSpriteRenderLevel) &&
|
||||
OpEqu(UserHacks_CPUCLUTRender) &&
|
||||
OpEqu(UserHacks_GPUTargetCLUTMode) &&
|
||||
OpEqu(UserHacks_TextureInsideRt) &&
|
||||
@ -717,6 +718,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
|
||||
GSSettingIntEx(UserHacks_TCOffsetX, "UserHacks_TCOffsetX");
|
||||
GSSettingIntEx(UserHacks_TCOffsetY, "UserHacks_TCOffsetY");
|
||||
GSSettingIntEx(UserHacks_CPUSpriteRenderBW, "UserHacks_CPUSpriteRenderBW");
|
||||
GSSettingIntEx(UserHacks_CPUSpriteRenderLevel, "UserHacks_CPUSpriteRenderLevel");
|
||||
GSSettingIntEx(UserHacks_CPUCLUTRender, "UserHacks_CPUCLUTRender");
|
||||
GSSettingIntEnumEx(UserHacks_GPUTargetCLUTMode, "UserHacks_GPUTargetCLUTMode");
|
||||
GSSettingIntEnumEx(TriFilter, "TriFilter");
|
||||
@ -792,6 +794,7 @@ void Pcsx2Config::GSOptions::MaskUserHacks()
|
||||
UserHacks_TCOffsetX = 0;
|
||||
UserHacks_TCOffsetY = 0;
|
||||
UserHacks_CPUSpriteRenderBW = 0;
|
||||
UserHacks_CPUSpriteRenderLevel = 0;
|
||||
UserHacks_CPUCLUTRender = 0;
|
||||
UserHacks_GPUTargetCLUTMode = GSGPUTargetCLUTMode::Disabled;
|
||||
SkipDrawStart = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user