GPU/HW: Fix filtered alpha blending in ROV path

This commit is contained in:
Stenzek 2025-05-17 14:04:11 +10:00
parent 401f2652ca
commit 3d8f6bf7aa
No known key found for this signature in database
2 changed files with 39 additions and 23 deletions

View File

@ -201,7 +201,7 @@ void GPU_HW_ShaderGen::WriteBatchTextureFilter(std::stringstream& ss, GPUTexture
// JINC2 and xBRZ shaders originally from beetle-psx, modified to support filtering mask channel. // JINC2 and xBRZ shaders originally from beetle-psx, modified to support filtering mask channel.
if (texture_filter == GPUTextureFilter::Bilinear || texture_filter == GPUTextureFilter::BilinearBinAlpha) if (texture_filter == GPUTextureFilter::Bilinear || texture_filter == GPUTextureFilter::BilinearBinAlpha)
{ {
DefineMacro(ss, "BINALPHA", texture_filter == GPUTextureFilter::BilinearBinAlpha); DefineMacro(ss, "TEXTURE_ALPHA_BLENDING", texture_filter != GPUTextureFilter::BilinearBinAlpha);
ss << R"( ss << R"(
void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limits, void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limits,
out float4 texcol, out float ialpha) out float4 texcol, out float ialpha)
@ -234,7 +234,7 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
if (ialpha > 0.0) if (ialpha > 0.0)
texcol.rgb /= float3(ialpha, ialpha, ialpha); texcol.rgb /= float3(ialpha, ialpha, ialpha);
#if BINALPHA #if !TEXTURE_ALPHA_BLENDING
ialpha = (ialpha >= 0.5) ? 1.0 : 0.0; ialpha = (ialpha >= 0.5) ? 1.0 : 0.0;
#endif #endif
} }
@ -265,7 +265,7 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
*/ */
DefineMacro(ss, "BINALPHA", texture_filter == GPUTextureFilter::JINC2BinAlpha); DefineMacro(ss, "TEXTURE_ALPHA_BLENDING", texture_filter != GPUTextureFilter::JINC2BinAlpha);
ss << R"( ss << R"(
CONSTANT float JINC2_WINDOW_SINC = 0.44; CONSTANT float JINC2_WINDOW_SINC = 0.44;
CONSTANT float JINC2_SINC = 0.82; CONSTANT float JINC2_SINC = 0.82;
@ -410,7 +410,7 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
if (ialpha > 0.0) if (ialpha > 0.0)
texcol.rgb /= float3(ialpha, ialpha, ialpha); texcol.rgb /= float3(ialpha, ialpha, ialpha);
#if BINALPHA #if !TEXTURE_ALPHA_BLENDING
ialpha = (ialpha >= 0.5) ? 1.0 : 0.0; ialpha = (ialpha >= 0.5) ? 1.0 : 0.0;
#endif #endif
} }
@ -442,7 +442,7 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
THE SOFTWARE. THE SOFTWARE.
*/ */
DefineMacro(ss, "BINALPHA", texture_filter == GPUTextureFilter::xBRBinAlpha); DefineMacro(ss, "TEXTURE_ALPHA_BLENDING", texture_filter == GPUTextureFilter::xBRBinAlpha);
ss << R"( ss << R"(
CONSTANT int BLEND_NONE = 0; CONSTANT int BLEND_NONE = 0;
CONSTANT int BLEND_NORMAL = 1; CONSTANT int BLEND_NORMAL = 1;
@ -718,7 +718,7 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
if (ialpha > 0.0) if (ialpha > 0.0)
texcol.rgb /= float3(ialpha, ialpha, ialpha); texcol.rgb /= float3(ialpha, ialpha, ialpha);
#if BINALPHA #if !TEXTURE_ALPHA_BLENDING
ialpha = (ialpha >= 0.5) ? 1.0 : 0.0; ialpha = (ialpha >= 0.5) ? 1.0 : 0.0;
#endif #endif
} }
@ -729,6 +729,8 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
} }
else if (texture_filter == GPUTextureFilter::MMPX) else if (texture_filter == GPUTextureFilter::MMPX)
{ {
DefineMacro(ss, "TEXTURE_ALPHA_BLENDING", false);
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";
@ -838,6 +840,7 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
else if (texture_filter == GPUTextureFilter::Scale2x) else if (texture_filter == GPUTextureFilter::Scale2x)
{ {
// Based on https://www.scale2x.it/algorithm // Based on https://www.scale2x.it/algorithm
DefineMacro(ss, "TEXTURE_ALPHA_BLENDING", false);
ss << R"( ss << R"(
#define src(xoffs, yoffs) packUnorm4x8(SampleFromVRAM(texpage, clamp(bcoords + float2((xoffs), (yoffs)), uv_limits.xy, uv_limits.zw))) #define src(xoffs, yoffs) packUnorm4x8(SampleFromVRAM(texpage, clamp(bcoords + float2((xoffs), (yoffs)), uv_limits.xy, uv_limits.zw)))
@ -870,6 +873,7 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
else if (texture_filter == GPUTextureFilter::Scale3x) else if (texture_filter == GPUTextureFilter::Scale3x)
{ {
// Based on https://www.scale2x.it/algorithm // Based on https://www.scale2x.it/algorithm
DefineMacro(ss, "TEXTURE_ALPHA_BLENDING", false);
ss << R"( ss << R"(
#define src(xoffs, yoffs) packUnorm4x8(SampleFromVRAM(texpage, clamp(bcoords + float2((xoffs), (yoffs)), uv_limits.xy, uv_limits.zw))) #define src(xoffs, yoffs) packUnorm4x8(SampleFromVRAM(texpage, clamp(bcoords + float2((xoffs), (yoffs)), uv_limits.xy, uv_limits.zw)))
@ -927,6 +931,10 @@ void FilteredSampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords, float4 uv_limi
#undef src #undef src
)"; )";
} }
else
{
DefineMacro(ss, "TEXTURE_ALPHA_BLENDING", false);
}
} }
std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader( std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(
@ -1302,14 +1310,21 @@ float4 SampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords)
bg_col.rgb = roundEven(bg_col.rgb * 31.0); bg_col.rgb = roundEven(bg_col.rgb * 31.0);
#endif #endif
#if TEXTURE_FILTERING
#if TRANSPARENCY_MODE == 0 || TRANSPARENCY_MODE == 3
bg_col.rgb /= ialpha;
#endif
fg_col.rgb *= ialpha;
#endif
o_col0.a = fg_col.a; o_col0.a = fg_col.a;
#if TEXTURE_FILTERING && TEXTURE_ALPHA_BLENDING
#if TRANSPARENCY_MODE == 0 // Half BG + Half FG.
o_col0.rgb = (bg_col.rgb * saturate(0.5 / ialpha)) + (fg_col.rgb * (ialpha * 0.5));
#elif TRANSPARENCY_MODE == 1 // BG + FG
o_col0.rgb = (bg_col.rgb * saturate(1.0 / ialpha)) + (fg_col.rgb * ialpha);
#elif TRANSPARENCY_MODE == 2 // BG - FG
o_col0.rgb = (bg_col.rgb * saturate(1.0 / ialpha)) - (fg_col.rgb * ialpha);
#elif TRANSPARENCY_MODE == 3 // BG + 1/4 FG.
o_col0.rgb = (bg_col.rgb * saturate(1.0 / ialpha)) + (fg_col.rgb * (0.25 * ialpha));
#else
o_col0.rgb = (fg_col.rgb * ialpha) + (bg_col.rgb * (1.0 - ialpha));
#endif
#else
#if TRANSPARENCY_MODE == 0 // Half BG + Half FG. #if TRANSPARENCY_MODE == 0 // Half BG + Half FG.
o_col0.rgb = (bg_col.rgb * 0.5) + (fg_col.rgb * 0.5); o_col0.rgb = (bg_col.rgb * 0.5) + (fg_col.rgb * 0.5);
#elif TRANSPARENCY_MODE == 1 // BG + FG #elif TRANSPARENCY_MODE == 1 // BG + FG
@ -1321,6 +1336,7 @@ float4 SampleFromVRAM(TEXPAGE_VALUE texpage, float2 coords)
#else #else
o_col0.rgb = fg_col.rgb; o_col0.rgb = fg_col.rgb;
#endif #endif
#endif
// 16-bit truncation. // 16-bit truncation.
#if !TRUE_COLOR && TRANSPARENCY #if !TRUE_COLOR && TRANSPARENCY

View File

@ -5,4 +5,4 @@
#include "common/types.h" #include "common/types.h"
static constexpr u32 SHADER_CACHE_VERSION = 32; static constexpr u32 SHADER_CACHE_VERSION = 33;