mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-28 14:20:30 +00:00
GPU/HW: Split MMPX to MMPX and MMPX Enhanced
This commit is contained in:
parent
98798fec66
commit
824b91a1f8
@ -727,9 +727,10 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
|
|||||||
|
|
||||||
)";
|
)";
|
||||||
}
|
}
|
||||||
else if (texture_filter == GPUTextureFilter::MMPX)
|
else if (texture_filter == GPUTextureFilter::MMPX || texture_filter == GPUTextureFilter::MMPXEnhanced)
|
||||||
{
|
{
|
||||||
DefineMacro(ss, "TEXTURE_ALPHA_BLENDING", false);
|
DefineMacro(ss, "TEXTURE_ALPHA_BLENDING", false);
|
||||||
|
DefineMacro(ss, "MMPX_ENHANCED", (texture_filter == GPUTextureFilter::MMPXEnhanced));
|
||||||
|
|
||||||
ss << "#define src(xoffs, yoffs) packUnorm4x8(SampleFromVRAM(texpage, clamp(bcoords + float2((xoffs), (yoffs)), "
|
ss << "#define src(xoffs, yoffs) packUnorm4x8(SampleFromVRAM(texpage, clamp(bcoords + float2((xoffs), (yoffs)), "
|
||||||
"uv_limits.xy, uv_limits.zw)))\n";
|
"uv_limits.xy, uv_limits.zw)))\n";
|
||||||
@ -742,7 +743,11 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
|
|||||||
ss << R"(
|
ss << R"(
|
||||||
uint luma(uint C) {
|
uint luma(uint C) {
|
||||||
uint alpha = (C & 0xFF000000u) >> 24;
|
uint alpha = (C & 0xFF000000u) >> 24;
|
||||||
|
#if MMPX_ENHANCED
|
||||||
return (((C & 0x00FF0000u) >> 16) + ((C & 0x0000FF00u) >> 8) + (C & 0x000000FFu)) + (255u - alpha) * 3;
|
return (((C & 0x00FF0000u) >> 16) + ((C & 0x0000FF00u) >> 8) + (C & 0x000000FFu)) + (255u - alpha) * 3;
|
||||||
|
#else
|
||||||
|
return (((C & 0x00FF0000u) >> 16) + ((C & 0x0000FF00u) >> 8) + (C & 0x000000FFu) + 1u) * (256u - alpha);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool all_eq2(uint B, uint A0, uint A1) {
|
bool all_eq2(uint B, uint A0, uint A1) {
|
||||||
@ -769,6 +774,8 @@ bool none_eq4(uint B, uint A0, uint A1, uint A2, uint A3) {
|
|||||||
return B != A0 && B != A1 && B != A2 && B != A3;
|
return B != A0 && B != A1 && B != A2 && B != A3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MMPX_ENHANCED
|
||||||
|
|
||||||
// Calculate the RGB distance between two ABGR8 colors
|
// Calculate the RGB distance between two ABGR8 colors
|
||||||
float rgb_distance(uint a, uint b)
|
float rgb_distance(uint a, uint b)
|
||||||
{
|
{
|
||||||
@ -876,6 +883,8 @@ bool countPatternMatches(uint LA, uint LB, uint L1, uint L2, uint L3, uint L4, u
|
|||||||
return score < 6; // Need to reach 6 points
|
return score < 6; // Need to reach 6 points
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limits, out float4 texcol, out float ialpha)
|
void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limits, out float4 texcol, out float ialpha)
|
||||||
{
|
{
|
||||||
float2 bcoords = floor(coords);
|
float2 bcoords = floor(coords);
|
||||||
@ -891,57 +900,44 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
|
|||||||
uint Q = src(-2, +0), R = src(+2, +0);
|
uint Q = src(-2, +0), R = src(+2, +0);
|
||||||
uint Bl = luma(B), Dl = luma(D), El = luma(E), Fl = luma(F), Hl = luma(H);
|
uint Bl = luma(B), Dl = luma(D), El = luma(E), Fl = luma(F), Hl = luma(H);
|
||||||
|
|
||||||
|
#if MMPX_ENHANCED
|
||||||
// Default to use center pixel E
|
// Default to use center pixel E
|
||||||
uint res = E;
|
ialpha = float(E != 0u);
|
||||||
|
texcol = unpackUnorm4x8(E);
|
||||||
|
|
||||||
// Check for "convex" patterns to avoid single-pixel spurs on long line edges
|
// Check for "convex" patterns to avoid single-pixel spurs on long line edges
|
||||||
if (A == B && B == C && E == H && A != D && C != F && rgb_distance(D, F) < 0.2 && rgb_distance(B, E) > 0.6) {
|
if (A == B && B == C && E == H && A != D && C != F && rgb_distance(D, F) < 0.2 && rgb_distance(B, E) > 0.6) {
|
||||||
ialpha = float(res != 0u);
|
|
||||||
texcol = unpackUnorm4x8(res);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (A == D && D == G && E == F && A != B && G != H && rgb_distance(B, H) < 0.2 && rgb_distance(D, E) > 0.6) {
|
if (A == D && D == G && E == F && A != B && G != H && rgb_distance(B, H) < 0.2 && rgb_distance(D, E) > 0.6) {
|
||||||
ialpha = float(res != 0u);
|
|
||||||
texcol = unpackUnorm4x8(res);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (C == F && F == I && E == D && B != C && H != I && rgb_distance(B, H) < 0.2 && rgb_distance(E, F) > 0.6) {
|
if (C == F && F == I && E == D && B != C && H != I && rgb_distance(B, H) < 0.2 && rgb_distance(E, F) > 0.6) {
|
||||||
ialpha = float(res != 0u);
|
|
||||||
texcol = unpackUnorm4x8(res);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G == H && H == I && B == E && D != G && F != I && rgb_distance(D, F) < 0.2 && rgb_distance(E, H) > 0.6) {
|
if (G == H && H == I && B == E && D != G && F != I && rgb_distance(D, F) < 0.2 && rgb_distance(E, H) > 0.6) {
|
||||||
ialpha = float(res != 0u);
|
|
||||||
texcol = unpackUnorm4x8(res);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check each 4-pixel intersection in a "grid" pattern and pass five surrounding pixels for pattern judgment
|
// Check each 4-pixel intersection in a "grid" pattern and pass five surrounding pixels for pattern judgment
|
||||||
if (A == E && B == D && A != B && countPatternMatches(A, B, C, F, I, H, G)) {
|
if (A == E && B == D && A != B && countPatternMatches(A, B, C, F, I, H, G)) {
|
||||||
ialpha = float(res != 0u);
|
|
||||||
texcol = unpackUnorm4x8(res);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (C == E && B == F && C != B && countPatternMatches(C, B, A, D, G, H, I)) {
|
if (C == E && B == F && C != B && countPatternMatches(C, B, A, D, G, H, I)) {
|
||||||
ialpha = float(res != 0u);
|
|
||||||
texcol = unpackUnorm4x8(res);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G == E && D == H && G != H && countPatternMatches(G, H, I, F, C, B, A)) {
|
if (G == E && D == H && G != H && countPatternMatches(G, H, I, F, C, B, A)) {
|
||||||
ialpha = float(res != 0u);
|
|
||||||
texcol = unpackUnorm4x8(res);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (I == E && F == H && I != H && countPatternMatches(I, H, G, D, A, B, C)) {
|
if (I == E && F == H && I != H && countPatternMatches(I, H, G, D, A, B, C)) {
|
||||||
ialpha = float(res != 0u);
|
|
||||||
texcol = unpackUnorm4x8(res);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Original MMPX logic
|
// Original MMPX logic
|
||||||
|
|
||||||
|
@ -1533,8 +1533,8 @@ GPURenderer Settings::GetAutomaticRenderer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constexpr const std::array s_texture_filter_names = {
|
static constexpr const std::array s_texture_filter_names = {
|
||||||
"Nearest", "Bilinear", "BilinearBinAlpha", "JINC2", "JINC2BinAlpha",
|
"Nearest", "Bilinear", "BilinearBinAlpha", "JINC2", "JINC2BinAlpha", "xBR",
|
||||||
"xBR", "xBRBinAlpha", "Scale2x", "Scale3x", "MMPX",
|
"xBRBinAlpha", "Scale2x", "Scale3x", "MMPX", "MMPXEnhanced",
|
||||||
};
|
};
|
||||||
static constexpr const std::array s_texture_filter_display_names = {
|
static constexpr const std::array s_texture_filter_display_names = {
|
||||||
TRANSLATE_DISAMBIG_NOOP("Settings", "Nearest-Neighbor", "GPUTextureFilter"),
|
TRANSLATE_DISAMBIG_NOOP("Settings", "Nearest-Neighbor", "GPUTextureFilter"),
|
||||||
@ -1547,6 +1547,7 @@ static constexpr const std::array s_texture_filter_display_names = {
|
|||||||
TRANSLATE_DISAMBIG_NOOP("Settings", "Scale2x (EPX)", "GPUTextureFilter"),
|
TRANSLATE_DISAMBIG_NOOP("Settings", "Scale2x (EPX)", "GPUTextureFilter"),
|
||||||
TRANSLATE_DISAMBIG_NOOP("Settings", "Scale3x (Slow)", "GPUTextureFilter"),
|
TRANSLATE_DISAMBIG_NOOP("Settings", "Scale3x (Slow)", "GPUTextureFilter"),
|
||||||
TRANSLATE_DISAMBIG_NOOP("Settings", "MMPX (Slow)", "GPUTextureFilter"),
|
TRANSLATE_DISAMBIG_NOOP("Settings", "MMPX (Slow)", "GPUTextureFilter"),
|
||||||
|
TRANSLATE_DISAMBIG_NOOP("Settings", "MMPX Enhanced (Slow)", "GPUTextureFilter"),
|
||||||
};
|
};
|
||||||
static_assert(s_texture_filter_names.size() == static_cast<size_t>(GPUTextureFilter::Count));
|
static_assert(s_texture_filter_names.size() == static_cast<size_t>(GPUTextureFilter::Count));
|
||||||
static_assert(s_texture_filter_display_names.size() == static_cast<size_t>(GPUTextureFilter::Count));
|
static_assert(s_texture_filter_display_names.size() == static_cast<size_t>(GPUTextureFilter::Count));
|
||||||
|
@ -100,6 +100,7 @@ enum class GPUTextureFilter : u8
|
|||||||
Scale2x,
|
Scale2x,
|
||||||
Scale3x,
|
Scale3x,
|
||||||
MMPX,
|
MMPX,
|
||||||
|
MMPXEnhanced,
|
||||||
Count
|
Count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user