mirror of https://github.com/PCSX2/pcsx2.git
GS: Support fractional upscale
This commit is contained in:
parent
44bad588b4
commit
6c17f7ad49
|
@ -288,9 +288,18 @@ PS_OUTPUT ps_convert_rgba_8i(PS_INPUT input)
|
|||
int txN = tb.x | (int(input.p.x) & 7);
|
||||
int txH = tb.x | ((int(input.p.x) + 4) & 7);
|
||||
|
||||
txN *= PS_SCALE_FACTOR;
|
||||
txH *= PS_SCALE_FACTOR;
|
||||
ty *= PS_SCALE_FACTOR;
|
||||
if (floor(PS_SCALE_FACTOR) != PS_SCALE_FACTOR)
|
||||
{
|
||||
txN = (int)((float)txN * PS_SCALE_FACTOR);
|
||||
txH = (int)((float)txH * PS_SCALE_FACTOR);
|
||||
ty = (int)((float)ty * PS_SCALE_FACTOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
txN *= PS_SCALE_FACTOR;
|
||||
txH *= PS_SCALE_FACTOR;
|
||||
ty *= PS_SCALE_FACTOR;
|
||||
}
|
||||
|
||||
// TODO investigate texture gather
|
||||
float4 cN = Texture.Load(int3(txN, ty, 0));
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#define PS_TALES_OF_ABYSS_HLE 0
|
||||
#define PS_URBAN_CHAOS_HLE 0
|
||||
#define PS_INVALID_TEX0 0
|
||||
#define PS_SCALE_FACTOR 1
|
||||
#define PS_SCALE_FACTOR 1.0
|
||||
#define PS_HDR 0
|
||||
#define PS_COLCLIP 0
|
||||
#define PS_BLEND_A 0
|
||||
|
|
|
@ -235,9 +235,18 @@ void ps_convert_rgba_8i()
|
|||
int txN = tb.x | (int(gl_FragCoord.x) & 7);
|
||||
int txH = tb.x | ((int(gl_FragCoord.x) + 4) & 7);
|
||||
|
||||
txN *= PS_SCALE_FACTOR;
|
||||
txH *= PS_SCALE_FACTOR;
|
||||
ty *= PS_SCALE_FACTOR;
|
||||
if (floor(PS_SCALE_FACTOR) != PS_SCALE_FACTOR)
|
||||
{
|
||||
txN = int(float(txN) * PS_SCALE_FACTOR);
|
||||
txH = int(float(txH) * PS_SCALE_FACTOR);
|
||||
ty = int(float(ty) * PS_SCALE_FACTOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
txN *= int(PS_SCALE_FACTOR);
|
||||
txH *= int(PS_SCALE_FACTOR);
|
||||
ty *= int(PS_SCALE_FACTOR);
|
||||
}
|
||||
|
||||
// TODO investigate texture gather
|
||||
vec4 cN = texelFetch(TextureSampler, ivec2(txN, ty), 0);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef PS_SCALE_FACTOR
|
||||
#define PS_SCALE_FACTOR 1
|
||||
#define PS_SCALE_FACTOR 1.0
|
||||
#endif
|
||||
|
||||
#ifdef VERTEX_SHADER
|
||||
|
@ -269,9 +269,18 @@ void ps_convert_rgba_8i()
|
|||
int txN = tb.x | (int(gl_FragCoord.x) & 7);
|
||||
int txH = tb.x | ((int(gl_FragCoord.x) + 4) & 7);
|
||||
|
||||
txN *= PS_SCALE_FACTOR;
|
||||
txH *= PS_SCALE_FACTOR;
|
||||
ty *= PS_SCALE_FACTOR;
|
||||
if (floor(PS_SCALE_FACTOR) != PS_SCALE_FACTOR)
|
||||
{
|
||||
txN = int(float(txN) * PS_SCALE_FACTOR);
|
||||
txH = int(float(txH) * PS_SCALE_FACTOR);
|
||||
ty = int(float(ty) * PS_SCALE_FACTOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
txN *= int(PS_SCALE_FACTOR);
|
||||
txH *= int(PS_SCALE_FACTOR);
|
||||
ty *= int(PS_SCALE_FACTOR);
|
||||
}
|
||||
|
||||
// TODO investigate texture gather
|
||||
vec4 cN = texelFetch(samp0, ivec2(txN, ty), 0);
|
||||
|
|
|
@ -333,7 +333,7 @@ void main()
|
|||
#define PS_TALES_OF_ABYSS_HLE 0
|
||||
#define PS_URBAN_CHAOS_HLE 0
|
||||
#define PS_INVALID_TEX0 0
|
||||
#define PS_SCALE_FACTOR 1
|
||||
#define PS_SCALE_FACTOR 1.0
|
||||
#define PS_HDR 0
|
||||
#define PS_COLCLIP 0
|
||||
#define PS_BLEND_A 0
|
||||
|
|
|
@ -177,7 +177,41 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
// HW Settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.upscaleMultiplier, "EmuCore/GS", "upscale_multiplier", 1, 1);
|
||||
static const char* upscale_entries[] = {
|
||||
"Native (PS2)",
|
||||
"1.25x Native",
|
||||
"1.5x Native",
|
||||
"1.75x Native",
|
||||
"2x Native (~720p)",
|
||||
"2.25x Native",
|
||||
"2.5x Native",
|
||||
"2.75x Native",
|
||||
"3x Native (~1080p)",
|
||||
"3.5x Native",
|
||||
"4x Native (~1440p/2K)",
|
||||
"5x Native (~1620p)",
|
||||
"6x Native (~2160p/4K)",
|
||||
"7x Native (~2520p)",
|
||||
"8x Native (~2880p)",
|
||||
nullptr};
|
||||
static const char* upscale_values[] = {
|
||||
"1",
|
||||
"1.25",
|
||||
"1.5",
|
||||
"1.75",
|
||||
"2",
|
||||
"2.25",
|
||||
"2.5",
|
||||
"2.75",
|
||||
"3",
|
||||
"3.5",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
nullptr };
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.upscaleMultiplier, "EmuCore/GS", "upscale_multiplier", upscale_entries, upscale_values, "1.0");
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureFiltering, "EmuCore/GS", "filter", static_cast<int>(BiFiltering::PS2));
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.trilinearFiltering, "EmuCore/GS", "TriFilter", static_cast<int>(TriFiltering::Automatic), -1);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(
|
||||
|
|
|
@ -388,48 +388,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="upscaleMultiplier">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Native (PS2)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2x Native (~720p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>3x Native (~1080p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4x Native (~1440p/2K)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>5x Native (~1620p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>6x Native (~2160p/4K)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>7x Native (~2520p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>8x Native (~2880p)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="upscaleMultiplier" />
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
|
|
|
@ -560,7 +560,7 @@ struct Pcsx2Config
|
|||
float OsdScale{100.0};
|
||||
|
||||
GSRendererType Renderer{GSRendererType::Auto};
|
||||
uint UpscaleMultiplier{1};
|
||||
float UpscaleMultiplier{1.0f};
|
||||
|
||||
HWMipmapLevel HWMipmap{HWMipmapLevel::Automatic};
|
||||
AccBlendLevel AccurateBlendingUnit{AccBlendLevel::Basic};
|
||||
|
|
|
@ -2534,16 +2534,40 @@ void FullscreenUI::DrawGraphicsSettingsPage()
|
|||
static constexpr const char* s_deinterlacing_options[] = {"None", "Weave (Top Field First, Sawtooth)",
|
||||
"Weave (Bottom Field First, Sawtooth)", "Bob (Top Field First)", "Bob (Bottom Field First)", "Blend (Top Field First, Half FPS)",
|
||||
"Blend (Bottom Field First, Half FPS)", "Automatic (Default)"};
|
||||
static constexpr const char* s_resolution_options[] = {
|
||||
static const char* s_resolution_options[] = {
|
||||
"Native (PS2)",
|
||||
"1.25x Native",
|
||||
"1.5x Native",
|
||||
"1.75x Native",
|
||||
"2x Native (~720p)",
|
||||
"2.25x Native",
|
||||
"2.5x Native",
|
||||
"2.75x Native",
|
||||
"3x Native (~1080p)",
|
||||
"3.5x Native",
|
||||
"4x Native (~1440p/2K)",
|
||||
"5x Native (~1620p)",
|
||||
"6x Native (~2160p/4K)",
|
||||
"7x Native (~2520p)",
|
||||
"8x Native (~2880p)",
|
||||
};
|
||||
static const char* s_resolution_values[] = {
|
||||
"1",
|
||||
"1.25",
|
||||
"1.5",
|
||||
"1.75",
|
||||
"2",
|
||||
"2.25",
|
||||
"2.5",
|
||||
"2.75",
|
||||
"3",
|
||||
"3.5",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
};
|
||||
static constexpr const char* s_mipmapping_options[] = {"Automatic (Default)", "Off", "Basic (Generated Mipmaps)", "Full (PS2 Mipmaps)"};
|
||||
static constexpr const char* s_bilinear_options[] = {
|
||||
"Nearest", "Bilinear (Forced)", "Bilinear (PS2)", "Bilinear (Forced excluding sprite)"};
|
||||
|
@ -2612,8 +2636,8 @@ void FullscreenUI::DrawGraphicsSettingsPage()
|
|||
MenuHeading("Rendering");
|
||||
if (is_hardware)
|
||||
{
|
||||
DrawIntListSetting(bsi, "Internal Resolution", "Multiplies the render resolution by the specified factor (upscaling).",
|
||||
"EmuCore/GS", "upscale_multiplier", 1, s_resolution_options, std::size(s_resolution_options), 1);
|
||||
DrawStringListSetting(bsi, "Internal Resolution", "Multiplies the render resolution by the specified factor (upscaling).",
|
||||
"EmuCore/GS", "upscale_multiplier", "1.000000", s_resolution_options, s_resolution_values, std::size(s_resolution_options));
|
||||
DrawIntListSetting(bsi, "Mipmapping", "Determines how mipmaps are used when rendering textures.", "EmuCore/GS", "mipmap_hw",
|
||||
static_cast<int>(HWMipmapLevel::Automatic), s_mipmapping_options, std::size(s_mipmapping_options), -1);
|
||||
DrawIntListSetting(bsi, "Bilinear Filtering", "Selects where bilinear filtering is utilized when rendering textures.", "EmuCore/GS",
|
||||
|
|
|
@ -51,7 +51,7 @@ GSState::GSState()
|
|||
{
|
||||
// m_nativeres seems to be a hack. Unfortunately it impacts draw call number which make debug painful in the replayer.
|
||||
// Let's keep it disabled to ease debug.
|
||||
m_nativeres = GSConfig.UpscaleMultiplier == 1;
|
||||
m_nativeres = GSConfig.UpscaleMultiplier == 1.0f;
|
||||
m_mipmap = GSConfig.Mipmap;
|
||||
|
||||
s_n = 0;
|
||||
|
|
|
@ -326,7 +326,7 @@ bool GSRenderer::Merge(int field)
|
|||
if (m_regs->SMODE2.FFMD && !is_bob && !GSConfig.DisableInterlaceOffset && GSConfig.InterlaceMode != GSInterlaceMode::Off)
|
||||
{
|
||||
// We do half because FFMD is a half sized framebuffer, then we offset by 1 in the shader for the actual interlace
|
||||
if(GetUpscaleMultiplier() > 1)
|
||||
if(GetUpscaleMultiplier() > 1.0f)
|
||||
interlace_offset += ((((tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y) + 0.5f) * 0.5f) - 1.0f) * static_cast<float>(field ^ field2);
|
||||
offset = 1.0f;
|
||||
}
|
||||
|
@ -363,7 +363,8 @@ bool GSRenderer::Merge(int field)
|
|||
resolution.y = std::min(max_resolution.y, resolution.y);
|
||||
}
|
||||
|
||||
fs = resolution * GSVector2i(GetUpscaleMultiplier());
|
||||
fs = GSVector2i(static_cast<int>(static_cast<float>(resolution.x) * GetUpscaleMultiplier()),
|
||||
static_cast<int>(static_cast<float>(resolution.y) * GetUpscaleMultiplier()));
|
||||
ds = fs;
|
||||
|
||||
// When interlace(FRAME) mode, the rect is half height, so it needs to be stretched.
|
||||
|
@ -545,12 +546,12 @@ static GSVector4i CalculateDrawSrcRect(const GSTexture* src)
|
|||
#ifndef PCSX2_CORE
|
||||
return GSVector4i(0, 0, src->GetWidth(), src->GetHeight());
|
||||
#else
|
||||
const int upscale = GSConfig.UpscaleMultiplier;
|
||||
const float upscale = GSConfig.UpscaleMultiplier;
|
||||
const GSVector2i size(src->GetSize());
|
||||
const int left = GSConfig.Crop[0] * upscale;
|
||||
const int top = GSConfig.Crop[1] * upscale;
|
||||
const int right = size.x - (GSConfig.Crop[2] * upscale);
|
||||
const int bottom = size.y - (GSConfig.Crop[3] * upscale);
|
||||
const int left = static_cast<int>(static_cast<float>(GSConfig.Crop[0]) * upscale);
|
||||
const int top = static_cast<int>(static_cast<float>(GSConfig.Crop[1]) * upscale);
|
||||
const int right = size.x - static_cast<int>(static_cast<float>(GSConfig.Crop[2]) * upscale);
|
||||
const int bottom = size.y - static_cast<int>(static_cast<float>(GSConfig.Crop[3]) * upscale);
|
||||
return GSVector4i(left, top, right, bottom);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
|
||||
virtual void VSync(u32 field, bool registers_written);
|
||||
virtual bool CanUpscale() { return false; }
|
||||
virtual int GetUpscaleMultiplier() { return 1; }
|
||||
virtual float GetUpscaleMultiplier() { return 1.0f; }
|
||||
virtual GSVector2 GetTextureScaleFactor() { return { 1.0f, 1.0f }; }
|
||||
GSVector2i GetInternalResolution();
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ bool GSDevice11::Create()
|
|||
}
|
||||
|
||||
ShaderMacro sm_convert(m_shader_cache.GetFeatureLevel());
|
||||
sm_convert.AddMacro("PS_SCALE_FACTOR", GSConfig.UpscaleMultiplier);
|
||||
sm_convert.AddMacro("PS_SCALE_FACTOR", StringUtil::ToChars(GSConfig.UpscaleMultiplier));
|
||||
|
||||
D3D_SHADER_MACRO* sm_convert_ptr = sm_convert.GetPtr();
|
||||
|
||||
|
@ -1312,7 +1312,12 @@ GSDevice11::ShaderMacro::ShaderMacro(D3D_FEATURE_LEVEL fl)
|
|||
|
||||
void GSDevice11::ShaderMacro::AddMacro(const char* n, int d)
|
||||
{
|
||||
mlist.emplace_back(n, std::to_string(d));
|
||||
AddMacro(n, std::to_string(d));
|
||||
}
|
||||
|
||||
void GSDevice11::ShaderMacro::AddMacro(const char* n, std::string d)
|
||||
{
|
||||
mlist.emplace_back(n, std::move(d));
|
||||
}
|
||||
|
||||
D3D_SHADER_MACRO* GSDevice11::ShaderMacro::GetPtr(void)
|
||||
|
|
|
@ -104,6 +104,7 @@ public:
|
|||
public:
|
||||
ShaderMacro(D3D_FEATURE_LEVEL fl);
|
||||
void AddMacro(const char* n, int d);
|
||||
void AddMacro(const char* n, std::string d);
|
||||
D3D_SHADER_MACRO* GetPtr(void);
|
||||
};
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ void GSDevice11::SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstant
|
|||
{
|
||||
ShaderMacro sm(m_shader_cache.GetFeatureLevel());
|
||||
|
||||
sm.AddMacro("PS_SCALE_FACTOR", GSConfig.UpscaleMultiplier);
|
||||
sm.AddMacro("PS_SCALE_FACTOR", StringUtil::ToChars(GSConfig.UpscaleMultiplier));
|
||||
sm.AddMacro("PS_FST", sel.fst);
|
||||
sm.AddMacro("PS_WMS", sel.wms);
|
||||
sm.AddMacro("PS_WMT", sel.wmt);
|
||||
|
|
|
@ -75,7 +75,12 @@ GSDevice12::ShaderMacro::ShaderMacro(D3D_FEATURE_LEVEL fl)
|
|||
|
||||
void GSDevice12::ShaderMacro::AddMacro(const char* n, int d)
|
||||
{
|
||||
mlist.emplace_back(n, std::to_string(d));
|
||||
AddMacro(n, std::to_string(d));
|
||||
}
|
||||
|
||||
void GSDevice12::ShaderMacro::AddMacro(const char* n, std::string d)
|
||||
{
|
||||
mlist.emplace_back(n, std::move(d));
|
||||
}
|
||||
|
||||
D3D_SHADER_MACRO* GSDevice12::ShaderMacro::GetPtr(void)
|
||||
|
@ -978,7 +983,7 @@ GSDevice12::ComPtr<ID3DBlob> GSDevice12::GetUtilityVertexShader(const std::strin
|
|||
GSDevice12::ComPtr<ID3DBlob> GSDevice12::GetUtilityPixelShader(const std::string& source, const char* entry_point)
|
||||
{
|
||||
ShaderMacro sm_model(m_shader_cache.GetFeatureLevel());
|
||||
sm_model.AddMacro("PS_SCALE_FACTOR", GSConfig.UpscaleMultiplier);
|
||||
sm_model.AddMacro("PS_SCALE_FACTOR", StringUtil::ToChars(GSConfig.UpscaleMultiplier));
|
||||
return m_shader_cache.GetPixelShader(source, sm_model.GetPtr(), entry_point);
|
||||
}
|
||||
|
||||
|
@ -1519,7 +1524,7 @@ const ID3DBlob* GSDevice12::GetTFXPixelShader(const GSHWDrawConfig::PSSelector&
|
|||
return it->second.get();
|
||||
|
||||
ShaderMacro sm(m_shader_cache.GetFeatureLevel());
|
||||
sm.AddMacro("PS_SCALE_FACTOR", GSConfig.UpscaleMultiplier);
|
||||
sm.AddMacro("PS_SCALE_FACTOR", StringUtil::ToChars(GSConfig.UpscaleMultiplier));
|
||||
sm.AddMacro("PS_FST", sel.fst);
|
||||
sm.AddMacro("PS_WMS", sel.wms);
|
||||
sm.AddMacro("PS_WMT", sel.wmt);
|
||||
|
|
|
@ -102,6 +102,7 @@ public:
|
|||
public:
|
||||
ShaderMacro(D3D_FEATURE_LEVEL fl);
|
||||
void AddMacro(const char* n, int d);
|
||||
void AddMacro(const char* n, std::string d);
|
||||
D3D_SHADER_MACRO* GetPtr(void);
|
||||
};
|
||||
|
||||
|
|
|
@ -93,7 +93,8 @@ GSVector2i GSRendererHW::GetOutputSize(int real_h)
|
|||
// Include negative display offsets in the height here.
|
||||
crtc_size.y = std::max(crtc_size.y, real_h);
|
||||
|
||||
return crtc_size * GSVector2i(static_cast<int>(GSConfig.UpscaleMultiplier), static_cast<int>(GSConfig.UpscaleMultiplier));
|
||||
return GSVector2i(static_cast<float>(crtc_size.x) * GSConfig.UpscaleMultiplier,
|
||||
static_cast<float>(crtc_size.y) * GSConfig.UpscaleMultiplier);
|
||||
}
|
||||
|
||||
void GSRendererHW::SetTCOffset()
|
||||
|
@ -171,10 +172,10 @@ void GSRendererHW::SetGameCRC(u32 crc, int options)
|
|||
|
||||
bool GSRendererHW::CanUpscale()
|
||||
{
|
||||
return GSConfig.UpscaleMultiplier != 1;
|
||||
return GSConfig.UpscaleMultiplier != 1.0f;
|
||||
}
|
||||
|
||||
int GSRendererHW::GetUpscaleMultiplier()
|
||||
float GSRendererHW::GetUpscaleMultiplier()
|
||||
{
|
||||
return GSConfig.UpscaleMultiplier;
|
||||
}
|
||||
|
@ -661,7 +662,7 @@ void GSRendererHW::ConvertSpriteTextureShuffle(bool& write_ba, bool& read_ba)
|
|||
|
||||
GSVector4 GSRendererHW::RealignTargetTextureCoordinate(const GSTextureCache::Source* tex)
|
||||
{
|
||||
if (GSConfig.UserHacks_HalfPixelOffset <= 1 || GetUpscaleMultiplier() == 1)
|
||||
if (GSConfig.UserHacks_HalfPixelOffset <= 1 || GetUpscaleMultiplier() == 1.0f)
|
||||
return GSVector4(0.0f);
|
||||
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
|
@ -798,7 +799,7 @@ void GSRendererHW::MergeSprite(GSTextureCache::Source* tex)
|
|||
|
||||
GSVector2 GSRendererHW::GetTextureScaleFactor()
|
||||
{
|
||||
const float f_upscale = static_cast<float>(GetUpscaleMultiplier());
|
||||
const float f_upscale = GetUpscaleMultiplier();
|
||||
return GSVector2(f_upscale, f_upscale);
|
||||
}
|
||||
|
||||
|
@ -835,7 +836,8 @@ GSVector2i GSRendererHW::GetTargetSize(GSVector2i* unscaled_size)
|
|||
|
||||
GL_INS("Target size for %x %u %u: %ux%u", m_context->FRAME.FBP, m_context->FRAME.FBW, m_context->FRAME.PSM, width, height);
|
||||
|
||||
return GSVector2i(static_cast<int>(width * GSConfig.UpscaleMultiplier), static_cast<int>(height * GSConfig.UpscaleMultiplier));
|
||||
return GSVector2i(static_cast<int>(static_cast<float>(width) * GSConfig.UpscaleMultiplier),
|
||||
static_cast<int>(static_cast<float>(height) * GSConfig.UpscaleMultiplier));
|
||||
}
|
||||
|
||||
void GSRendererHW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r)
|
||||
|
@ -1963,7 +1965,7 @@ void GSRendererHW::SetupIA(const float& sx, const float& sy)
|
|||
for (unsigned int i = 0; i < m_vertex.next; i++)
|
||||
m_vertex.buff[i].UV &= 0x3FEF3FEF;
|
||||
}
|
||||
const bool unscale_pt_ln = !GSConfig.UserHacks_DisableSafeFeatures && (GetUpscaleMultiplier() != 1);
|
||||
const bool unscale_pt_ln = !GSConfig.UserHacks_DisableSafeFeatures && (GetUpscaleMultiplier() != 1.0f);
|
||||
const GSDevice::FeatureSupport features = g_gs_device->Features();
|
||||
|
||||
ASSERT(VerifyIndices());
|
||||
|
|
|
@ -177,7 +177,7 @@ public:
|
|||
|
||||
void SetGameCRC(u32 crc, int options) override;
|
||||
bool CanUpscale() override;
|
||||
int GetUpscaleMultiplier() override;
|
||||
float GetUpscaleMultiplier() override;
|
||||
void Lines2Sprites();
|
||||
bool VerifyIndices();
|
||||
template <GSHWDrawConfig::VSExpand Expand> void ExpandIndices();
|
||||
|
|
|
@ -1864,8 +1864,8 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
|
||||
if (GSConfig.UserHacks_HalfPixelOffset == 1 && hack)
|
||||
{
|
||||
modxy = static_cast<float>(g_gs_renderer->GetUpscaleMultiplier());
|
||||
switch (g_gs_renderer->GetUpscaleMultiplier())
|
||||
modxy = g_gs_renderer->GetUpscaleMultiplier();
|
||||
switch (static_cast<int>(std::round(g_gs_renderer->GetUpscaleMultiplier())))
|
||||
{
|
||||
case 2: case 4: case 6: case 8: modxy += 0.2f; break;
|
||||
case 3: case 7: modxy += 0.1f; break;
|
||||
|
|
|
@ -611,9 +611,8 @@ bool GSDeviceMTL::Create()
|
|||
m_draw_sync_fence = MRCTransfer([m_dev.dev newFence]);
|
||||
|
||||
m_fn_constants = MRCTransfer([MTLFunctionConstantValues new]);
|
||||
u8 upscale = std::max(1, theApp.GetConfigI("upscale_multiplier"));
|
||||
vector_uchar2 upscale2 = vector2(upscale, upscale);
|
||||
[m_fn_constants setConstantValue:&upscale2 type:MTLDataTypeUChar2 atIndex:GSMTLConstantIndex_SCALING_FACTOR];
|
||||
vector_float2 upscale2 = vector2(GSConfig.UpscaleMultiplier, GSConfig.UpscaleMultiplier);
|
||||
[m_fn_constants setConstantValue:&upscale2 type:MTLDataTypeFloat2 atIndex:GSMTLConstantIndex_SCALING_FACTOR];
|
||||
setFnConstantB(m_fn_constants, m_dev.features.framebuffer_fetch, GSMTLConstantIndex_FRAMEBUFFER_FETCH);
|
||||
|
||||
m_hw_vertex = MRCTransfer([MTLVertexDescriptor new]);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
using namespace metal;
|
||||
|
||||
constant uchar2 SCALING_FACTOR [[function_constant(GSMTLConstantIndex_SCALING_FACTOR)]];
|
||||
constant float2 SCALING_FACTOR [[function_constant(GSMTLConstantIndex_SCALING_FACTOR)]];
|
||||
|
||||
struct ConvertShaderData
|
||||
{
|
||||
|
|
|
@ -268,9 +268,18 @@ fragment float4 ps_convert_rgba_8i(ConvertShaderData data [[stage_in]], ConvertP
|
|||
uint txN = tb.x | (uint(data.p.x) & 7);
|
||||
uint txH = tb.x | ((uint(data.p.x) + 4) & 7);
|
||||
|
||||
txN *= SCALING_FACTOR.x;
|
||||
txH *= SCALING_FACTOR.x;
|
||||
ty *= SCALING_FACTOR.y;
|
||||
if (floor(SCALING_FACTOR.x) != SCALING_FACTOR.x)
|
||||
{
|
||||
txN = (int)((float)txN * SCALING_FACTOR.x);
|
||||
txH = (int)((float)txH * SCALING_FACTOR.x);
|
||||
ty = (int)((float)ty * SCALING_FACTOR.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
txN *= SCALING_FACTOR.x;
|
||||
txH *= SCALING_FACTOR.x;
|
||||
ty *= SCALING_FACTOR.y;
|
||||
}
|
||||
|
||||
// TODO investigate texture gather
|
||||
float4 cN = res.texture.read(uint2(txN, ty));
|
||||
|
|
|
@ -502,7 +502,7 @@ struct PSMain
|
|||
|
||||
float4 sample_depth(float2 st)
|
||||
{
|
||||
float2 uv_f = float2(clamp_wrap_uv_depth(ushort2(st))) * (float2(SCALING_FACTOR) * float2(1.f / 16.f));
|
||||
float2 uv_f = float2(clamp_wrap_uv_depth(ushort2(st))) * (SCALING_FACTOR * float2(1.f / 16.f));
|
||||
ushort2 uv = ushort2(uv_f);
|
||||
|
||||
float4 t = float4(0);
|
||||
|
@ -778,7 +778,7 @@ struct PSMain
|
|||
if (PS_DITHER == 2)
|
||||
fpos = ushort2(in.p.xy);
|
||||
else
|
||||
fpos = ushort2(in.p.xy / float2(SCALING_FACTOR));
|
||||
fpos = ushort2(in.p.xy / SCALING_FACTOR);
|
||||
C.rgb += cb.dither_matrix[fpos.y & 3][fpos.x & 3];
|
||||
}
|
||||
|
||||
|
|
|
@ -237,7 +237,7 @@ bool GSDeviceOGL::Create()
|
|||
|
||||
GLint point_range[2] = {};
|
||||
glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, point_range);
|
||||
m_features.point_expand = (point_range[0] <= static_cast<GLint>(GSConfig.UpscaleMultiplier) && point_range[1] >= static_cast<GLint>(GSConfig.UpscaleMultiplier));
|
||||
m_features.point_expand = (point_range[0] <= GSConfig.UpscaleMultiplier && point_range[1] >= GSConfig.UpscaleMultiplier);
|
||||
|
||||
Console.WriteLn("Using %s for point expansion.", m_features.point_expand ? "hardware" : "geometry shaders");
|
||||
|
||||
|
@ -380,7 +380,7 @@ bool GSDeviceOGL::Create()
|
|||
{
|
||||
const char* name = shaderName(static_cast<ShaderConvert>(i));
|
||||
const std::string macro_sel = (static_cast<ShaderConvert>(i) == ShaderConvert::RGBA_TO_8I) ?
|
||||
StringUtil::StdStringFromFormat("#define PS_SCALE_FACTOR %d\n", GSConfig.UpscaleMultiplier) :
|
||||
fmt::format("#define PS_SCALE_FACTOR {}\n", GSConfig.UpscaleMultiplier) :
|
||||
std::string();
|
||||
const std::string ps(GetShaderSource(name, GL_FRAGMENT_SHADER, m_shader_common_header, *convert_glsl, macro_sel));
|
||||
if (!m_shader_cache.GetProgram(&m_convert.ps[i], m_convert.vs, {}, ps))
|
||||
|
@ -456,7 +456,7 @@ bool GSDeviceOGL::Create()
|
|||
|
||||
for (size_t i = 0; i < std::size(m_merge_obj.ps); i++)
|
||||
{
|
||||
const std::string ps(GetShaderSource(StringUtil::StdStringFromFormat("ps_main%d", i), GL_FRAGMENT_SHADER, m_shader_common_header, *shader, {}));
|
||||
const std::string ps(GetShaderSource(fmt::format("ps_main{}", i), GL_FRAGMENT_SHADER, m_shader_common_header, *shader, {}));
|
||||
if (!m_shader_cache.GetProgram(&m_merge_obj.ps[i], m_convert.vs, {}, ps))
|
||||
return false;
|
||||
m_merge_obj.ps[i].SetFormattedName("Merge pipe %zu", i);
|
||||
|
@ -479,7 +479,7 @@ bool GSDeviceOGL::Create()
|
|||
|
||||
for (size_t i = 0; i < std::size(m_interlace.ps); i++)
|
||||
{
|
||||
const std::string ps(GetShaderSource(StringUtil::StdStringFromFormat("ps_main%d", i), GL_FRAGMENT_SHADER, m_shader_common_header, *shader, {}));
|
||||
const std::string ps(GetShaderSource(fmt::format("ps_main{}", i), GL_FRAGMENT_SHADER, m_shader_common_header, *shader, {}));
|
||||
if (!m_shader_cache.GetProgram(&m_interlace.ps[i], m_convert.vs, {}, ps))
|
||||
return false;
|
||||
m_interlace.ps[i].SetFormattedName("Merge pipe %zu", i);
|
||||
|
@ -538,7 +538,7 @@ bool GSDeviceOGL::Create()
|
|||
for (size_t i = 0; i < std::size(m_date.primid_ps); i++)
|
||||
{
|
||||
const std::string ps(GetShaderSource(
|
||||
StringUtil::StdStringFromFormat("ps_stencil_image_init_%d", i),
|
||||
fmt::format("ps_stencil_image_init_{}", i),
|
||||
GL_FRAGMENT_SHADER, m_shader_common_header, *convert_glsl, {}));
|
||||
m_shader_cache.GetProgram(&m_date.primid_ps[i], m_convert.vs, {}, ps);
|
||||
m_date.primid_ps[i].SetFormattedName("PrimID Destination Alpha Init %d", i);
|
||||
|
@ -1027,11 +1027,11 @@ std::string GSDeviceOGL::GetVSSource(VSSelector sel)
|
|||
Console.WriteLn("Compiling new vertex shader with selector 0x%" PRIX64, sel.key);
|
||||
#endif
|
||||
|
||||
std::string macro = StringUtil::StdStringFromFormat("#define VS_INT_FST %d\n", sel.int_fst)
|
||||
+ StringUtil::StdStringFromFormat("#define VS_IIP %d\n", sel.iip)
|
||||
+ StringUtil::StdStringFromFormat("#define VS_POINT_SIZE %d\n", sel.point_size);
|
||||
std::string macro = fmt::format("#define VS_INT_FST {}\n", static_cast<u32>(sel.int_fst))
|
||||
+ fmt::format("#define VS_IIP {}\n", static_cast<u32>(sel.iip))
|
||||
+ fmt::format("#define VS_POINT_SIZE {}\n", static_cast<u32>(sel.point_size));
|
||||
if (sel.point_size)
|
||||
macro += StringUtil::StdStringFromFormat("#define VS_POINT_SIZE_VALUE %d\n", GSConfig.UpscaleMultiplier);
|
||||
macro += fmt::format("#define VS_POINT_SIZE_VALUE {}\n", GSConfig.UpscaleMultiplier);
|
||||
|
||||
std::string src = GenGlslHeader("vs_main", GL_VERTEX_SHADER, macro);
|
||||
src += m_shader_common_header;
|
||||
|
@ -1045,9 +1045,9 @@ std::string GSDeviceOGL::GetGSSource(GSSelector sel)
|
|||
Console.WriteLn("Compiling new geometry shader with selector 0x%" PRIX64, sel.key);
|
||||
#endif
|
||||
|
||||
std::string macro = StringUtil::StdStringFromFormat("#define GS_POINT %d\n", sel.point)
|
||||
+ StringUtil::StdStringFromFormat("#define GS_LINE %d\n", sel.line)
|
||||
+ StringUtil::StdStringFromFormat("#define GS_IIP %d\n", sel.iip);
|
||||
std::string macro = fmt::format("#define GS_POINT {}\n", static_cast<u32>(sel.point))
|
||||
+ fmt::format("#define GS_LINE {}\n", static_cast<u32>(sel.line))
|
||||
+ fmt::format("#define GS_IIP {}\n", static_cast<u32>(sel.iip));
|
||||
|
||||
std::string src = GenGlslHeader("gs_main", GL_GEOMETRY_SHADER, macro);
|
||||
src += m_shader_common_header;
|
||||
|
@ -1061,53 +1061,53 @@ std::string GSDeviceOGL::GetPSSource(const PSSelector& sel)
|
|||
Console.WriteLn("Compiling new pixel shader with selector 0x%" PRIX64 "%08X", sel.key_hi, sel.key_lo);
|
||||
#endif
|
||||
|
||||
std::string macro = StringUtil::StdStringFromFormat("#define PS_FST %d\n", sel.fst)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_WMS %d\n", sel.wms)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_WMT %d\n", sel.wmt)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_AEM_FMT %d\n", sel.aem_fmt)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_PAL_FMT %d\n", sel.pal_fmt)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_DFMT %d\n", sel.dfmt)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_DEPTH_FMT %d\n", sel.depth_fmt)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_CHANNEL_FETCH %d\n", sel.channel)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_URBAN_CHAOS_HLE %d\n", sel.urban_chaos_hle)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_TALES_OF_ABYSS_HLE %d\n", sel.tales_of_abyss_hle)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_TEX_IS_FB %d\n", sel.tex_is_fb)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_INVALID_TEX0 %d\n", sel.invalid_tex0)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_AEM %d\n", sel.aem)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_TFX %d\n", sel.tfx)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_TCC %d\n", sel.tcc)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_ATST %d\n", sel.atst)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_FOG %d\n", sel.fog)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_CLR_HW %d\n", sel.clr_hw)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_FBA %d\n", sel.fba)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_LTF %d\n", sel.ltf)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_AUTOMATIC_LOD %d\n", sel.automatic_lod)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_MANUAL_LOD %d\n", sel.manual_lod)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_COLCLIP %d\n", sel.colclip)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_DATE %d\n", sel.date)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_TCOFFSETHACK %d\n", sel.tcoffsethack)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_POINT_SAMPLER %d\n", sel.point_sampler)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_BLEND_A %d\n", sel.blend_a)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_BLEND_B %d\n", sel.blend_b)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_BLEND_C %d\n", sel.blend_c)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_BLEND_D %d\n", sel.blend_d)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_IIP %d\n", sel.iip)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_SHUFFLE %d\n", sel.shuffle)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_READ_BA %d\n", sel.read_ba)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_WRITE_RG %d\n", sel.write_rg)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_FBMASK %d\n", sel.fbmask)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_HDR %d\n", sel.hdr)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_DITHER %d\n", sel.dither)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_ZCLAMP %d\n", sel.zclamp)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_BLEND_MIX %d\n", sel.blend_mix)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_FIXED_ONE_A %d\n", sel.fixed_one_a)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_PABE %d\n", sel.pabe)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_SCANMSK %d\n", sel.scanmsk)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_SCALE_FACTOR %d\n", GSConfig.UpscaleMultiplier)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_NO_COLOR %d\n", sel.no_color)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_NO_COLOR1 %d\n", sel.no_color1)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_NO_ABLEND %d\n", sel.no_ablend)
|
||||
+ StringUtil::StdStringFromFormat("#define PS_ONLY_ALPHA %d\n", sel.only_alpha)
|
||||
std::string macro = fmt::format("#define PS_FST {}\n", sel.fst)
|
||||
+ fmt::format("#define PS_WMS {}\n", sel.wms)
|
||||
+ fmt::format("#define PS_WMT {}\n", sel.wmt)
|
||||
+ fmt::format("#define PS_AEM_FMT {}\n", sel.aem_fmt)
|
||||
+ fmt::format("#define PS_PAL_FMT {}\n", sel.pal_fmt)
|
||||
+ fmt::format("#define PS_DFMT {}\n", sel.dfmt)
|
||||
+ fmt::format("#define PS_DEPTH_FMT {}\n", sel.depth_fmt)
|
||||
+ fmt::format("#define PS_CHANNEL_FETCH {}\n", sel.channel)
|
||||
+ fmt::format("#define PS_URBAN_CHAOS_HLE {}\n", sel.urban_chaos_hle)
|
||||
+ fmt::format("#define PS_TALES_OF_ABYSS_HLE {}\n", sel.tales_of_abyss_hle)
|
||||
+ fmt::format("#define PS_TEX_IS_FB {}\n", sel.tex_is_fb)
|
||||
+ fmt::format("#define PS_INVALID_TEX0 {}\n", sel.invalid_tex0)
|
||||
+ fmt::format("#define PS_AEM {}\n", sel.aem)
|
||||
+ fmt::format("#define PS_TFX {}\n", sel.tfx)
|
||||
+ fmt::format("#define PS_TCC {}\n", sel.tcc)
|
||||
+ fmt::format("#define PS_ATST {}\n", sel.atst)
|
||||
+ fmt::format("#define PS_FOG {}\n", sel.fog)
|
||||
+ fmt::format("#define PS_CLR_HW {}\n", sel.clr_hw)
|
||||
+ fmt::format("#define PS_FBA {}\n", sel.fba)
|
||||
+ fmt::format("#define PS_LTF {}\n", sel.ltf)
|
||||
+ fmt::format("#define PS_AUTOMATIC_LOD {}\n", sel.automatic_lod)
|
||||
+ fmt::format("#define PS_MANUAL_LOD {}\n", sel.manual_lod)
|
||||
+ fmt::format("#define PS_COLCLIP {}\n", sel.colclip)
|
||||
+ fmt::format("#define PS_DATE {}\n", sel.date)
|
||||
+ fmt::format("#define PS_TCOFFSETHACK {}\n", sel.tcoffsethack)
|
||||
+ fmt::format("#define PS_POINT_SAMPLER {}\n", sel.point_sampler)
|
||||
+ fmt::format("#define PS_BLEND_A {}\n", sel.blend_a)
|
||||
+ fmt::format("#define PS_BLEND_B {}\n", sel.blend_b)
|
||||
+ fmt::format("#define PS_BLEND_C {}\n", sel.blend_c)
|
||||
+ fmt::format("#define PS_BLEND_D {}\n", sel.blend_d)
|
||||
+ fmt::format("#define PS_IIP {}\n", sel.iip)
|
||||
+ fmt::format("#define PS_SHUFFLE {}\n", sel.shuffle)
|
||||
+ fmt::format("#define PS_READ_BA {}\n", sel.read_ba)
|
||||
+ fmt::format("#define PS_WRITE_RG {}\n", sel.write_rg)
|
||||
+ fmt::format("#define PS_FBMASK {}\n", sel.fbmask)
|
||||
+ fmt::format("#define PS_HDR {}\n", sel.hdr)
|
||||
+ fmt::format("#define PS_DITHER {}\n", sel.dither)
|
||||
+ fmt::format("#define PS_ZCLAMP {}\n", sel.zclamp)
|
||||
+ fmt::format("#define PS_BLEND_MIX {}\n", sel.blend_mix)
|
||||
+ fmt::format("#define PS_FIXED_ONE_A {}\n", sel.fixed_one_a)
|
||||
+ fmt::format("#define PS_PABE {}\n", sel.pabe)
|
||||
+ fmt::format("#define PS_SCANMSK {}\n", sel.scanmsk)
|
||||
+ fmt::format("#define PS_SCALE_FACTOR {}\n", GSConfig.UpscaleMultiplier)
|
||||
+ fmt::format("#define PS_NO_COLOR {}\n", sel.no_color)
|
||||
+ fmt::format("#define PS_NO_COLOR1 {}\n", sel.no_color1)
|
||||
+ fmt::format("#define PS_NO_ABLEND {}\n", sel.no_ablend)
|
||||
+ fmt::format("#define PS_ONLY_ALPHA {}\n", sel.only_alpha)
|
||||
;
|
||||
|
||||
std::string src = GenGlslHeader("ps_main", GL_FRAGMENT_SHADER, macro);
|
||||
|
@ -1130,7 +1130,7 @@ bool GSDeviceOGL::DownloadTexture(GSTexture* src, const GSVector4i& rect, GSText
|
|||
// Copy a sub part of texture (same as below but force a conversion)
|
||||
void GSDeviceOGL::BlitRect(GSTexture* sTex, const GSVector4i& r, const GSVector2i& dsize, bool at_origin, bool linear)
|
||||
{
|
||||
GL_PUSH(StringUtil::StdStringFromFormat("CopyRectConv from %d", static_cast<GSTextureOGL*>(sTex)->GetID()).c_str());
|
||||
GL_PUSH(fmt::format("CopyRectConv from {}", static_cast<GSTextureOGL*>(sTex)->GetID()).c_str());
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
|
||||
// NOTE: This previously used glCopyTextureSubImage2D(), but this appears to leak memory in
|
||||
|
|
|
@ -1102,7 +1102,7 @@ VkShaderModule GSDeviceVK::GetUtilityVertexShader(const std::string& source, con
|
|||
std::stringstream ss;
|
||||
AddShaderHeader(ss);
|
||||
AddShaderStageMacro(ss, true, false, false);
|
||||
AddMacro(ss, "PS_SCALE_FACTOR", GSConfig.UpscaleMultiplier);
|
||||
AddMacro(ss, "PS_SCALE_FACTOR", StringUtil::ToChars(GSConfig.UpscaleMultiplier).c_str());
|
||||
if (replace_main)
|
||||
ss << "#define " << replace_main << " main\n";
|
||||
ss << source;
|
||||
|
@ -1115,7 +1115,7 @@ VkShaderModule GSDeviceVK::GetUtilityFragmentShader(const std::string& source, c
|
|||
std::stringstream ss;
|
||||
AddShaderHeader(ss);
|
||||
AddShaderStageMacro(ss, false, false, true);
|
||||
AddMacro(ss, "PS_SCALE_FACTOR", GSConfig.UpscaleMultiplier);
|
||||
AddMacro(ss, "PS_SCALE_FACTOR", StringUtil::ToChars(GSConfig.UpscaleMultiplier).c_str());
|
||||
if (replace_main)
|
||||
ss << "#define " << replace_main << " main\n";
|
||||
ss << source;
|
||||
|
@ -1894,7 +1894,7 @@ VkShaderModule GSDeviceVK::GetTFXVertexShader(GSHWDrawConfig::VSSelector sel)
|
|||
AddMacro(ss, "VS_IIP", sel.iip);
|
||||
AddMacro(ss, "VS_POINT_SIZE", sel.point_size);
|
||||
if (sel.point_size)
|
||||
AddMacro(ss, "VS_POINT_SIZE_VALUE", GSConfig.UpscaleMultiplier);
|
||||
AddMacro(ss, "VS_POINT_SIZE_VALUE", StringUtil::ToChars(GSConfig.UpscaleMultiplier).c_str());
|
||||
ss << m_tfx_source;
|
||||
|
||||
VkShaderModule mod = g_vulkan_shader_cache->GetVertexShader(ss.str());
|
||||
|
@ -1978,7 +1978,7 @@ VkShaderModule GSDeviceVK::GetTFXFragmentShader(const GSHWDrawConfig::PSSelector
|
|||
AddMacro(ss, "PS_ZCLAMP", sel.zclamp);
|
||||
AddMacro(ss, "PS_PABE", sel.pabe);
|
||||
AddMacro(ss, "PS_SCANMSK", sel.scanmsk);
|
||||
AddMacro(ss, "PS_SCALE_FACTOR", GSConfig.UpscaleMultiplier);
|
||||
AddMacro(ss, "PS_SCALE_FACTOR", StringUtil::ToChars(GSConfig.UpscaleMultiplier).c_str());
|
||||
AddMacro(ss, "PS_TEX_IS_FB", sel.tex_is_fb);
|
||||
AddMacro(ss, "PS_NO_COLOR", sel.no_color);
|
||||
AddMacro(ss, "PS_NO_COLOR1", sel.no_color1);
|
||||
|
|
|
@ -458,13 +458,13 @@ bool GameDatabaseSchema::GameEntry::configMatchesHWFix(const Pcsx2Config::GSOpti
|
|||
return (static_cast<int>(config.UserHacks_TextureInsideRt) == value);
|
||||
|
||||
case GSHWFixId::AlignSprite:
|
||||
return (config.UpscaleMultiplier == 1 || static_cast<int>(config.UserHacks_AlignSpriteX) == value);
|
||||
return (config.UpscaleMultiplier <= 1.0f || static_cast<int>(config.UserHacks_AlignSpriteX) == value);
|
||||
|
||||
case GSHWFixId::MergeSprite:
|
||||
return (config.UpscaleMultiplier == 1 || static_cast<int>(config.UserHacks_MergePPSprite) == value);
|
||||
return (config.UpscaleMultiplier <= 1.0f || static_cast<int>(config.UserHacks_MergePPSprite) == value);
|
||||
|
||||
case GSHWFixId::WildArmsHack:
|
||||
return (config.UpscaleMultiplier == 1 || static_cast<int>(config.UserHacks_WildHack) == value);
|
||||
return (config.UpscaleMultiplier <= 1.0f || static_cast<int>(config.UserHacks_WildHack) == value);
|
||||
|
||||
case GSHWFixId::PointListPalette:
|
||||
return (static_cast<int>(config.PointListPalette) == value);
|
||||
|
@ -485,10 +485,10 @@ bool GameDatabaseSchema::GameEntry::configMatchesHWFix(const Pcsx2Config::GSOpti
|
|||
return (config.UserHacks_HalfBottomOverride == value);
|
||||
|
||||
case GSHWFixId::HalfPixelOffset:
|
||||
return (config.UpscaleMultiplier == 1 || config.UserHacks_HalfPixelOffset == value);
|
||||
return (config.UpscaleMultiplier <= 1.0f || config.UserHacks_HalfPixelOffset == value);
|
||||
|
||||
case GSHWFixId::RoundSprite:
|
||||
return (config.UpscaleMultiplier == 1 || config.UserHacks_RoundSprite == value);
|
||||
return (config.UpscaleMultiplier <= 1.0f || config.UserHacks_RoundSprite == value);
|
||||
|
||||
case GSHWFixId::TexturePreloading:
|
||||
return (static_cast<int>(config.TexturePreloading) <= value);
|
||||
|
|
|
@ -500,7 +500,8 @@ void Pcsx2Config::GSOptions::LoadSaveIniSettings(SettingsWrapper& wrap)
|
|||
#define GSSettingIntEx(var, name) SettingsWrapBitfieldEx(var, name)
|
||||
#define GSSettingBool(var) SettingsWrapBitBool(var)
|
||||
#define GSSettingBoolEx(var, name) SettingsWrapBitBoolEx(var, name)
|
||||
#define GSSettingFloat(var) SettingsWrapBitfield(var)
|
||||
#define GSSettingFloat(var) SettingsWrapEntry(var)
|
||||
#define GSSettingFloatEx(var, name) SettingsWrapEntryEx(var, name)
|
||||
#define GSSettingIntEnumEx(var, name) SettingsWrapIntEnumEx(var, name)
|
||||
#define GSSettingString(var) SettingsWrapEntry(var)
|
||||
#define GSSettingStringEx(var, name) SettingsWrapEntryEx(var, name)
|
||||
|
@ -515,6 +516,7 @@ void Pcsx2Config::GSOptions::ReloadIniSettings()
|
|||
#define GSSettingBool(var) var = theApp.GetConfigB(#var)
|
||||
#define GSSettingBoolEx(var, name) var = theApp.GetConfigB(name)
|
||||
#define GSSettingFloat(var) var = static_cast<float>(theApp.GetConfigI(#var))
|
||||
#define GSSettingFloatEx(var, name) var = static_cast<float>(theApp.GetConfigI(name))
|
||||
#define GSSettingIntEnumEx(var, name) var = static_cast<decltype(var)>(theApp.GetConfigI(name))
|
||||
#define GSSettingString(var) var = theApp.GetConfigS(#var)
|
||||
#define GSSettingStringEx(var, name) var = theApp.GetConfigS(name)
|
||||
|
@ -583,8 +585,10 @@ void Pcsx2Config::GSOptions::ReloadIniSettings()
|
|||
GSSettingFloat(OsdScale);
|
||||
|
||||
GSSettingIntEnumEx(Renderer, "Renderer");
|
||||
GSSettingIntEx(UpscaleMultiplier, "upscale_multiplier");
|
||||
UpscaleMultiplier = std::clamp(UpscaleMultiplier, 1u, 8u);
|
||||
GSSettingFloatEx(UpscaleMultiplier, "upscale_multiplier");
|
||||
|
||||
// ~51x would the upper bound here for 32768x32768 textures, but you'll run out VRAM long before then.
|
||||
UpscaleMultiplier = std::clamp(UpscaleMultiplier, 0.5f, 50.0f);
|
||||
|
||||
GSSettingIntEnumEx(HWMipmap, "mipmap_hw");
|
||||
GSSettingIntEnumEx(AccurateBlendingUnit, "accurate_blending_unit");
|
||||
|
@ -661,7 +665,7 @@ void Pcsx2Config::GSOptions::MaskUserHacks()
|
|||
|
||||
void Pcsx2Config::GSOptions::MaskUpscalingHacks()
|
||||
{
|
||||
if (UpscaleMultiplier != 1 && ManualUserHacks)
|
||||
if (UpscaleMultiplier > 1.0f && ManualUserHacks)
|
||||
return;
|
||||
|
||||
UserHacks_AlignSpriteX = false;
|
||||
|
|
|
@ -15,4 +15,4 @@
|
|||
|
||||
/// Version number for GS and other shaders. Increment whenever any of the contents of the
|
||||
/// shaders change, to invalidate the cache.
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 10;
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 11;
|
||||
|
|
|
@ -407,7 +407,7 @@ void VMManager::RequestDisplaySize(float scale /*= 0.0f*/)
|
|||
if (scale != 0.0f)
|
||||
{
|
||||
// unapply the upscaling, then apply the scale
|
||||
scale = (1.0f / static_cast<float>(GSConfig.UpscaleMultiplier)) * scale;
|
||||
scale = (1.0f / GSConfig.UpscaleMultiplier) * scale;
|
||||
width *= scale;
|
||||
height *= scale;
|
||||
}
|
||||
|
@ -1829,6 +1829,8 @@ void VMManager::WarnAboutUnsafeSettings()
|
|||
messages += ICON_FA_TACHOMETER_ALT " Cycle rate/skip is not at default, this may crash or make games run too slow.\n";
|
||||
if (EmuConfig.SPU2.SynchMode != Pcsx2Config::SPU2Options::SynchronizationMode::TimeStretch)
|
||||
messages += ICON_FA_VOLUME_MUTE " Audio is not using time stretch synchronization, this may break FMVs.\n";
|
||||
if (EmuConfig.GS.UpscaleMultiplier < 1.0f)
|
||||
messages += ICON_FA_TV " Upscale multiplier is below native, this will break rendering.\n";
|
||||
if (EmuConfig.GS.HWMipmap != HWMipmapLevel::Automatic)
|
||||
messages += ICON_FA_IMAGES " Mipmapping is not set to automatic. This may break rendering in some games.\n";
|
||||
if (EmuConfig.GS.TextureFiltering != BiFiltering::PS2)
|
||||
|
|
Loading…
Reference in New Issue