ios: bundle resources from bin and converge on the runtime overlay

Point the iOS Xcode/CMake resource bundling at the canonical bin/resources tree
instead of a committed iOS copy, mirroring the desktop and Android builds. The
GLOBs now embed bin/resources fonts/shaders/sounds and the top-level GameDB /
Redump / controller data into the app bundle's Resources/, excluding the dx11
shaders iOS never compiles (it renders with Metal).

iOS also drops its bespoke build-time GameDB merge (tools/gamedb-convert.py plus
its GameIndex[original]/[override].yaml inputs) and instead bundles the canonical
mobile overlay bin/resources-overlay/armsx2_overrides.yaml, which the shared
GameDatabase override loader applies at runtime from EmuFolders::Resources — the
same path every other platform now uses. This converges iOS onto Android's
mobile GS/JIT tuning (its committed GameIndex was stale — older Tekken clamp,
missing the Ziemas and Crazy Frog fixes) and onto one override code path.

Delete the 41 committed iOS resource duplicates; patches.zip stays as the only
iOS-only extra. Needs a macOS/Xcode build to confirm the bundled Resources/.
This commit is contained in:
Brian Degenhardt
2026-07-22 21:16:45 -07:00
parent a62543d497
commit ea351894e8
45 changed files with 18 additions and 237345 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,52 +0,0 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Roboto
Upstream-Contact: https://github.com/google/roboto/issues
Source: git clone https://github.com/google/roboto
Comment: Tarball created from git clone using this command:
git archive HEAD --format=tar
Files: *
Copyright: 2015, Google Inc.
License: Apache-2.0
Files: hinted/*
out/*
scripts/lib/*
src/v2/*
scripts/render.sh
scripts/build-v2.py
scripts/run_exhaustive_tests.py
scripts/coverage_test.py
scripts/touchup_for_web.py
scripts/temporary_touchups.py
scripts/run_web_tests.py
scripts/touchup_for_android.py
scripts/roboto_data.py
scripts/force_yminmax.py
scripts/run_general_tests.py
Copyright: 2015, Google Inc.
License: Apache-2.0
Files: scripts/subset_for_web.py
third_party/fontcrunch/*
Copyright: 2014, Google Inc.
License: Apache-2.0
Files: third_party/spiro/*
Copyright: 2007, Raph Levien
License: GPL-2+
Files: debian/*
Copyright: 2015, Vasudev Kamath <vasudev@copyninja.info>
2015, Jonas Smedegaard <dr@jones.dk>
License: GPL-3+
License: Apache-2.0
License-Reference: /usr/share/common-licenses/Apache-2.0
License: GPL-2+
License-Reference: /usr/share/common-licenses/GPL-2
License: GPL-3+
License-Reference: /usr/share/common-licenses/GPL-3
@@ -1,91 +0,0 @@
This Font Software is licensed under the SIL Open Font License,
Version 1.1. This license is copied below, and is also available
with a FAQ at <http: //scripts.sil.org/OFL>
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,498 +0,0 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#ifndef FXAA_HLSL
#define FXAA_HLSL 0
#endif
#ifndef FXAA_GLSL_130
#define FXAA_GLSL_130 0
#endif
#ifndef FXAA_GLSL_VK
#define FXAA_GLSL_VK 0
#endif
#define UHQ_FXAA 1 //High Quality Fast Approximate Anti Aliasing. Adapted for GS from Timothy Lottes FXAA 3.11.
#define FxaaSubpixMax 0.0 //[0.00 to 1.00] Amount of subpixel aliasing removal. 0.00: Edge only antialiasing (no blurring)
#define FxaaEarlyExit 1 //[0 or 1] Use Fxaa early exit pathing. When disabled, the entire scene is antialiased(FSAA). 0 is off, 1 is on.
/*------------------------------------------------------------------------------
[GLOBALS|FUNCTIONS]
------------------------------------------------------------------------------*/
#if (FXAA_GLSL_130 == 1)
in vec2 PSin_t;
layout(location = 0) out vec4 SV_Target0;
layout(binding = 0) uniform sampler2D TextureSampler;
#elif (FXAA_GLSL_VK == 1)
layout(location = 0) in vec2 PSin_t;
layout(location = 0) out vec4 SV_Target0;
layout(set = 0, binding = 0) uniform sampler2D TextureSampler;
#elif (FXAA_HLSL == 1)
Texture2D Texture : register(t0);
SamplerState TextureSampler : register(s0);
struct VS_INPUT
{
float4 p : POSITION;
float2 t : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
};
struct PS_OUTPUT
{
float4 c : SV_Target0;
};
#elif defined(__METAL_VERSION__)
static constexpr sampler MAIN_SAMPLER(coord::normalized, address::clamp_to_edge, filter::linear);
#endif
/*------------------------------------------------------------------------------
[FXAA CODE SECTION]
------------------------------------------------------------------------------*/
#if (FXAA_HLSL == 1)
struct FxaaTex { SamplerState smpl; Texture2D tex; };
#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
#define FxaaDiscard clip(-1)
#define FxaaSat(x) saturate(x)
#elif (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
#define int2 ivec2
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define FxaaDiscard discard
#define FxaaSat(x) clamp(x, 0.0, 1.0)
#define FxaaTex sampler2D
#define FxaaTexTop(t, p) textureLod(t, p, 0.0)
#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
#elif defined(__METAL_VERSION__)
#define FxaaTex texture2d<float>
#define FxaaTexTop(t, p) t.sample(MAIN_SAMPLER, p)
#define FxaaTexOff(t, p, o, r) t.sample(MAIN_SAMPLER, p, o)
#define FxaaDiscard discard_fragment()
#define FxaaSat(x) saturate(x)
#endif
#define FxaaEdgeThreshold 0.063
#define FxaaEdgeThresholdMin 0.00
#define FXAA_QUALITY_P0 1.0
#define FXAA_QUALITY_P1 1.5
#define FXAA_QUALITY_P2 2.0
#define FXAA_QUALITY_P3 2.0
#define FXAA_QUALITY_P4 2.0
#define FXAA_QUALITY_P5 2.0
#define FXAA_QUALITY_P6 2.0
#define FXAA_QUALITY_P7 2.0
#define FXAA_QUALITY_P8 2.0
#define FXAA_QUALITY_P9 2.0
#define FXAA_QUALITY_P10 4.0
#define FXAA_QUALITY_P11 8.0
#define FXAA_QUALITY_P12 8.0
/*------------------------------------------------------------------------------
[GAMMA PREPASS CODE SECTION]
------------------------------------------------------------------------------*/
float RGBLuminance(float3 color)
{
const float3 lumCoeff = float3(0.2126729, 0.7151522, 0.0721750);
return dot(color.rgb, lumCoeff);
}
float3 RGBGammaToLinear(float3 color, float gamma)
{
color = FxaaSat(color);
color.r = (color.r <= 0.0404482362771082) ?
color.r / 12.92 : pow((color.r + 0.055) / 1.055, gamma);
color.g = (color.g <= 0.0404482362771082) ?
color.g / 12.92 : pow((color.g + 0.055) / 1.055, gamma);
color.b = (color.b <= 0.0404482362771082) ?
color.b / 12.92 : pow((color.b + 0.055) / 1.055, gamma);
return color;
}
float3 LinearToRGBGamma(float3 color, float gamma)
{
color = FxaaSat(color);
color.r = (color.r <= 0.00313066844250063) ?
color.r * 12.92 : 1.055 * pow(color.r, 1.0 / gamma) - 0.055;
color.g = (color.g <= 0.00313066844250063) ?
color.g * 12.92 : 1.055 * pow(color.g, 1.0 / gamma) - 0.055;
color.b = (color.b <= 0.00313066844250063) ?
color.b * 12.92 : 1.055 * pow(color.b, 1.0 / gamma) - 0.055;
return color;
}
float4 PreGammaPass(float4 color)
{
const float GammaConst = 2.233;
color.rgb = RGBGammaToLinear(color.rgb, GammaConst);
color.rgb = LinearToRGBGamma(color.rgb, GammaConst);
color.a = RGBLuminance(color.rgb);
return color;
}
/*------------------------------------------------------------------------------
[FXAA CODE SECTION]
------------------------------------------------------------------------------*/
float FxaaLuma(float4 rgba)
{
rgba.w = RGBLuminance(rgba.xyz);
return rgba.w;
}
float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaSubpix, float fxaaEdgeThreshold, float fxaaEdgeThresholdMin)
{
float2 posM = pos;
float4 rgbyM = FxaaTexTop(tex, posM);
rgbyM.w = RGBLuminance(rgbyM.xyz);
#define lumaM rgbyM.w
float lumaS = FxaaLuma(FxaaTexOff(tex, posM, int2( 0, 1), fxaaRcpFrame.xy));
float lumaE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1, 0), fxaaRcpFrame.xy));
float lumaN = FxaaLuma(FxaaTexOff(tex, posM, int2( 0,-1), fxaaRcpFrame.xy));
float lumaW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1, 0), fxaaRcpFrame.xy));
float maxSM = max(lumaS, lumaM);
float minSM = min(lumaS, lumaM);
float maxESM = max(lumaE, maxSM);
float minESM = min(lumaE, minSM);
float maxWN = max(lumaN, lumaW);
float minWN = min(lumaN, lumaW);
float rangeMax = max(maxWN, maxESM);
float rangeMin = min(minWN, minESM);
float range = rangeMax - rangeMin;
float rangeMaxScaled = rangeMax * fxaaEdgeThreshold;
float rangeMaxClamped = max(fxaaEdgeThresholdMin, rangeMaxScaled);
#if (FxaaEarlyExit == 1)
// Potential optimization, early exit.
if (range < rangeMaxClamped)
return rgbyM;
#endif
float lumaNW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1,-1), fxaaRcpFrame.xy));
float lumaSE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1, 1), fxaaRcpFrame.xy));
float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1,-1), fxaaRcpFrame.xy));
float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1, 1), fxaaRcpFrame.xy));
float lumaNS = lumaN + lumaS;
float lumaWE = lumaW + lumaE;
float subpixRcpRange = 1.0/range;
float subpixNSWE = lumaNS + lumaWE;
float edgeHorz1 = (-2.0 * lumaM) + lumaNS;
float edgeVert1 = (-2.0 * lumaM) + lumaWE;
float lumaNESE = lumaNE + lumaSE;
float lumaNWNE = lumaNW + lumaNE;
float edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
float edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
float lumaNWSW = lumaNW + lumaSW;
float lumaSWSE = lumaSW + lumaSE;
float edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
float edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
float edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
float edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
float edgeHorz = abs(edgeHorz3) + edgeHorz4;
float edgeVert = abs(edgeVert3) + edgeVert4;
float subpixNWSWNESE = lumaNWSW + lumaNESE;
float lengthSign = fxaaRcpFrame.x;
bool horzSpan = edgeHorz >= edgeVert;
float subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
if(!horzSpan) lumaN = lumaW;
if(!horzSpan) lumaS = lumaE;
if(horzSpan) lengthSign = fxaaRcpFrame.y;
float subpixB = (subpixA * (1.0/12.0)) - lumaM;
float gradientN = lumaN - lumaM;
float gradientS = lumaS - lumaM;
float lumaNN = lumaN + lumaM;
float lumaSS = lumaS + lumaM;
bool pairN = abs(gradientN) >= abs(gradientS);
float gradient = max(abs(gradientN), abs(gradientS));
if(pairN) lengthSign = -lengthSign;
float subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);
float2 posB;
posB.x = posM.x;
posB.y = posM.y;
float2 offNP;
offNP.x = (!horzSpan) ? 0.0 : fxaaRcpFrame.x;
offNP.y = ( horzSpan) ? 0.0 : fxaaRcpFrame.y;
if(!horzSpan) posB.x += lengthSign * 0.5;
if( horzSpan) posB.y += lengthSign * 0.5;
float2 posN;
posN.x = posB.x - offNP.x * FXAA_QUALITY_P0;
posN.y = posB.y - offNP.y * FXAA_QUALITY_P0;
float2 posP;
posP.x = posB.x + offNP.x * FXAA_QUALITY_P0;
posP.y = posB.y + offNP.y * FXAA_QUALITY_P0;
float subpixD = ((-2.0)*subpixC) + 3.0;
float lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
float subpixE = subpixC * subpixC;
float lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));
if(!pairN) lumaNN = lumaSS;
float gradientScaled = gradient * 1.0/4.0;
float lumaMM = lumaM - lumaNN * 0.5;
float subpixF = subpixD * subpixE;
bool lumaMLTZero = lumaMM < 0.0;
lumaEndN -= lumaNN * 0.5;
lumaEndP -= lumaNN * 0.5;
bool doneN = abs(lumaEndN) >= gradientScaled;
bool doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1;
bool doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11;
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12;
}}}}}}}}}}}
float dstN = posM.x - posN.x;
float dstP = posP.x - posM.x;
if(!horzSpan) dstN = posM.y - posN.y;
if(!horzSpan) dstP = posP.y - posM.y;
bool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
float spanLength = (dstP + dstN);
bool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
float spanLengthRcp = 1.0/spanLength;
bool directionN = dstN < dstP;
float dst = min(dstN, dstP);
bool goodSpan = directionN ? goodSpanN : goodSpanP;
float subpixG = subpixF * subpixF;
float pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
float subpixH = subpixG * fxaaSubpix;
float pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
float pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
return float4(FxaaTexTop(tex, posM).xyz, lumaM);
}
#if (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
float4 FxaaPass(float4 FxaaColor, float2 uv0)
#elif (FXAA_HLSL == 1)
float4 FxaaPass(float4 FxaaColor : COLOR0, float2 uv0 : TEXCOORD0)
#elif defined(__METAL_VERSION__)
float4 FxaaPass(float4 FxaaColor, float2 uv0, texture2d<float> tex)
#endif
{
#if (FXAA_HLSL == 1)
FxaaTex tex;
tex.tex = Texture;
tex.smpl = TextureSampler;
float2 PixelSize;
Texture.GetDimensions(PixelSize.x, PixelSize.y);
FxaaColor = FxaaPixelShader(uv0, tex, 1.0/PixelSize.xy, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin);
#elif (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
vec2 PixelSize = vec2(textureSize(TextureSampler, 0));
FxaaColor = FxaaPixelShader(uv0, TextureSampler, 1.0/PixelSize.xy, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin);
#elif defined(__METAL_VERSION__)
float2 PixelSize = float2(tex.get_width(), tex.get_height());
FxaaColor = FxaaPixelShader(uv0, tex, 1.f/PixelSize, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin);
#endif
return FxaaColor;
}
/*------------------------------------------------------------------------------
[MAIN() & COMBINE PASS CODE SECTION]
------------------------------------------------------------------------------*/
#if (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
void main()
{
vec4 color = texture(TextureSampler, PSin_t);
color = PreGammaPass(color);
color = FxaaPass(color, PSin_t);
SV_Target0 = float4(color.rgb, 1.0);
}
#elif (FXAA_HLSL == 1)
PS_OUTPUT main(VS_OUTPUT input)
{
PS_OUTPUT output;
float4 color = Texture.Sample(TextureSampler, input.t);
color = PreGammaPass(color);
color = FxaaPass(color, input.t);
output.c = float4(color.rgb, 1.0);
return output;
}
// Metal main function in in fxaa.metal
#endif
@@ -1,75 +0,0 @@
// Based on CAS_Shader.hlsl
//
// Copyright(c) 2019 Advanced Micro Devices, Inc.All rights reserved.
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
cbuffer cb : register(b0)
{
uint4 const0;
uint4 const1;
int2 srcOffset;
};
Texture2D InputTexture : register(t0);
RWTexture2D<float4> OutputTexture : register(u0);
#define A_GPU 1
#define A_HLSL 1
#include "ffx_a.h"
AF3 CasLoad(ASU2 p)
{
return InputTexture.Load(int3(srcOffset, 0) + int3(p, 0)).rgb;
}
// Lets you transform input from the load into a linear color space between 0 and 1. See ffx_cas.h
// In this case, our input is already linear and between 0 and 1
void CasInput(inout AF1 r, inout AF1 g, inout AF1 b) {}
#include "ffx_cas.h"
[numthreads(64, 1, 1)]
void main(uint3 LocalThreadId : SV_GroupThreadID, uint3 WorkGroupId : SV_GroupID)
{
// Do remapping of local xy in workgroup for a more PS-like swizzle pattern.
AU2 gxy = ARmp8x8(LocalThreadId.x) + AU2(WorkGroupId.x << 4u, WorkGroupId.y << 4u);
#if CAS_SHARPEN_ONLY
const bool sharpenOnly = true;
#else
const bool sharpenOnly = false;
#endif
// Filter.
AF3 c = (float3)0.0f;
CasFilter(c.r, c.g, c.b, gxy, const0, const1, sharpenOnly);
OutputTexture[ASU2(gxy)] = AF4(c, 1);
gxy.x += 8u;
CasFilter(c.r, c.g, c.b, gxy, const0, const1, sharpenOnly);
OutputTexture[ASU2(gxy)] = AF4(c, 1);
gxy.y += 8u;
CasFilter(c.r, c.g, c.b, gxy, const0, const1, sharpenOnly);
OutputTexture[ASU2(gxy)] = AF4(c, 1);
gxy.x -= 8u;
CasFilter(c.r, c.g, c.b, gxy, const0, const1, sharpenOnly);
OutputTexture[ASU2(gxy)] = AF4(c, 1);
}
File diff suppressed because it is too large Load Diff
@@ -1,39 +0,0 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
cbuffer vertexBuffer : register(b0)
{
float4x4 ProjectionMatrix;
};
struct VS_INPUT
{
float2 pos : POSITION;
float4 col : COLOR0;
float2 uv : TEXCOORD0;
};
struct PS_INPUT
{
float4 pos : SV_POSITION;
float4 col : COLOR0;
float2 uv : TEXCOORD0;
};
PS_INPUT vs_main(VS_INPUT input)
{
PS_INPUT output;
output.pos = mul(ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));
output.col = input.col;
output.uv = input.uv;
return output;
}
sampler sampler0 : register(s0);
Texture2D texture0 : register(t0);
float4 ps_main(PS_INPUT input) : SV_Target
{
float4 out_col = input.col * texture0.Sample(sampler0, input.uv);
return out_col;
}
@@ -1,183 +0,0 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
Texture2D Texture;
SamplerState Sampler;
cbuffer cb0
{
float4 ZrH;
};
struct PS_INPUT
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
};
// Weave shader
float4 ps_main0(PS_INPUT input) : SV_Target0
{
const int idx = int(ZrH.x); // buffer index passed from CPU
const int field = idx & 1; // current field
const int vpos = int(input.p.y); // vertical position of destination texture
if ((vpos & 1) == field)
return Texture.SampleLevel(Sampler, input.t, 0);
else
discard;
return float4(0.0f, 0.0f, 0.0f, 0.0f);
}
// Bob shader
float4 ps_main1(PS_INPUT input) : SV_Target0
{
return Texture.SampleLevel(Sampler, input.t, 0);
}
// Blend shader
float4 ps_main2(PS_INPUT input) : SV_Target0
{
float2 vstep = float2(0.0f, ZrH.y);
float4 c0 = Texture.SampleLevel(Sampler, input.t - vstep, 0);
float4 c1 = Texture.SampleLevel(Sampler, input.t, 0);
float4 c2 = Texture.SampleLevel(Sampler, input.t + vstep, 0);
return (c0 + c1 * 2 + c2) / 4;
}
// MAD shader - buffering
float4 ps_main3(PS_INPUT input) : SV_Target0
{
// We take half the lines from the current frame and stores them in the MAD frame buffer.
// the MAD frame buffer is split in 2 consecutive banks of 2 fields each, the fields in each bank
// are interleaved (top field at even lines and bottom field at odd lines).
// When the source texture has an odd vres, the first line of bank 1 would be an odd index
// causing the wrong lines to be discarded, so a vertical offset (lofs) is added to the vertical
// position of the destination texture to force the proper field alignment
const int idx = int(ZrH.x); // buffer index passed from CPU
const int bank = idx >> 1; // current bank
const int field = idx & 1; // current field
const int vres = int(ZrH.z) >> 1; // vertical resolution of source texture
const int lofs = ((((vres + 1) >> 1) << 1) - vres) & bank; // line alignment offset for bank 1
const int vpos = int(input.p.y) + lofs; // vertical position of destination texture
// if the index of current destination line belongs to the current fiels we update it, otherwise
// we leave the old line in the destination buffer
if ((vpos & 1) == field)
return Texture.SampleLevel(Sampler, input.t, 0);
else
discard;
return float4(0.0f, 0.0f, 0.0f, 0.0f);
}
// MAD shader - reconstruction
float4 ps_main4(PS_INPUT input) : SV_Target0
{
// we use the contents of the MAD frame buffer to reconstruct the missing lines from the current
// field.
const int idx = int(ZrH.x); // buffer index passed from CPU
const int field = idx & 1; // current field
const int vpos = int(input.p.y); // vertical position of destination texture
const float sensitivity = ZrH.w; // passed from CPU, higher values mean more likely to use weave
const float3 motion_thr = float3(1.0, 1.0, 1.0) * sensitivity; //
const float2 bofs = float2(0.0f, 0.5f); // position of the bank 1 relative to source texture size
const float2 vscale = float2(1.0f, 0.5f); // scaling factor from source to destination texture
const float2 lofs = float2(0.0f, ZrH.y) * vscale; // distance between two adjacent lines relative to source texture size
const float2 iptr = input.t * vscale; // pointer to the current pixel in the source texture
float2 p_t0; // pointer to current pixel (missing or not) from most recent frame
float2 p_t1; // pointer to current pixel (missing or not) from one frame back
float2 p_t2; // pointer to current pixel (missing or not) from two frames back
float2 p_t3; // pointer to current pixel (missing or not) from three frames back
switch (idx)
{
case 1:
p_t0 = iptr;
p_t1 = iptr;
p_t2 = iptr + bofs;
p_t3 = iptr + bofs;
break;
case 2:
p_t0 = iptr + bofs;
p_t1 = iptr;
p_t2 = iptr;
p_t3 = iptr + bofs;
break;
case 3:
p_t0 = iptr + bofs;
p_t1 = iptr + bofs;
p_t2 = iptr;
p_t3 = iptr;
break;
default:
p_t0 = iptr;
p_t1 = iptr + bofs;
p_t2 = iptr + bofs;
p_t3 = iptr;
break;
}
// calculating motion, only relevant for missing lines where the "center line" is pointed by p_t1
float4 hn = Texture.SampleLevel(Sampler, p_t0 - lofs, 0); // new high pixel
float4 cn = Texture.SampleLevel(Sampler, p_t1, 0); // new center pixel
float4 ln = Texture.SampleLevel(Sampler, p_t0 + lofs, 0); // new low pixel
float4 ho = Texture.SampleLevel(Sampler, p_t2 - lofs, 0); // old high pixel
float4 co = Texture.SampleLevel(Sampler, p_t3, 0); // old center pixel
float4 lo = Texture.SampleLevel(Sampler, p_t2 + lofs, 0); // old low pixel
float3 mh = hn.rgb - ho.rgb; // high pixel motion
float3 mc = cn.rgb - co.rgb; // center pixel motion
float3 ml = ln.rgb - lo.rgb; // low pixel motion
mh = max(mh, -mh) - motion_thr;
mc = max(mc, -mc) - motion_thr;
ml = max(ml, -ml) - motion_thr;
#if 1 // use this code to evaluate each color motion separately
float mh_max = max(max(mh.x, mh.y), mh.z);
float mc_max = max(max(mc.x, mc.y), mc.z);
float ml_max = max(max(ml.x, ml.y), ml.z);
#else // use this code to evaluate average color motion
float mh_max = mh.x + mh.y + mh.z;
float mc_max = mc.x + mc.y + mc.z;
float ml_max = ml.x + ml.y + ml.z;
#endif
// selecting deinterlacing output
if ((vpos & 1) == field)
{
// output coordinate present on current field
return Texture.SampleLevel(Sampler, p_t0, 0);
}
else if ((iptr.y > 0.5f - lofs.y) || (iptr.y < 0.0 + lofs.y))
{
// top and bottom lines are always weaved
return cn;
}
else
{
// missing line needs to be reconstructed
if (((mh_max > 0.0f) || (ml_max > 0.0f)) || (mc_max > 0.0f))
// high motion -> interpolate pixels above and below
return (hn + ln) / 2.0f;
else
// low motion -> weave
return cn;
}
return float4(0.0f, 0.0f, 0.0f, 0.0f);
}
@@ -1,33 +0,0 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
Texture2D Texture;
SamplerState Sampler;
cbuffer cb0 : register(b0)
{
float4 BGColor;
int EMODA;
int EMODC;
int cb0_pad[2];
};
struct PS_INPUT
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
};
float4 ps_main0(PS_INPUT input) : SV_Target0
{
float4 c = Texture.Sample(Sampler, input.t);
c.a *= 2.0f;
return c;
}
float4 ps_main1(PS_INPUT input) : SV_Target0
{
float4 c = Texture.Sample(Sampler, input.t);
c.a = BGColor.a;
return c;
}
@@ -1,480 +0,0 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
struct VS_INPUT
{
float4 p : POSITION;
float2 t : TEXCOORD0;
float4 c : COLOR;
};
struct VS_OUTPUT
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
float4 c : COLOR;
};
cbuffer cb0 : register(b0)
{
float4 u_source_rect;
float4 u_target_rect;
float2 u_source_size;
float2 u_target_size;
float2 u_target_resolution;
float2 u_rcp_target_resolution; // 1 / u_target_resolution
float2 u_source_resolution;
float2 u_rcp_source_resolution; // 1 / u_source_resolution
float u_time;
};
Texture2D Texture;
SamplerState TextureSampler;
float4 sample_c(float2 uv)
{
return Texture.Sample(TextureSampler, uv);
}
struct PS_INPUT
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
float4 c : COLOR;
};
struct PS_OUTPUT
{
float4 c : SV_Target0;
};
VS_OUTPUT vs_main(VS_INPUT input)
{
VS_OUTPUT output;
output.p = input.p;
output.t = input.t;
output.c = input.c;
return output;
}
PS_OUTPUT ps_copy(PS_INPUT input)
{
PS_OUTPUT output;
output.c = sample_c(input.t);
return output;
}
float4 ps_crt(PS_INPUT input, int i)
{
float4 mask[4] =
{
float4(1, 0, 0, 0),
float4(0, 1, 0, 0),
float4(0, 0, 1, 0),
float4(1, 1, 1, 0)
};
return sample_c(input.t) * saturate(mask[i] + 0.5f);
}
float4 ps_scanlines(PS_INPUT input, int i)
{
float4 mask[2] =
{
float4(1, 1, 1, 0),
float4(0, 0, 0, 0)
};
return sample_c(input.t) * saturate(mask[i] + 0.5f);
}
PS_OUTPUT ps_filter_scanlines(PS_INPUT input)
{
PS_OUTPUT output;
uint4 p = (uint4)input.p;
output.c = ps_scanlines(input, p.y % 2);
return output;
}
PS_OUTPUT ps_filter_diagonal(PS_INPUT input)
{
PS_OUTPUT output;
uint4 p = (uint4)input.p;
output.c = ps_crt(input, (p.x + (p.y % 3)) % 3);
return output;
}
PS_OUTPUT ps_filter_triangular(PS_INPUT input)
{
PS_OUTPUT output;
uint4 p = (uint4)input.p;
// output.c = ps_crt(input, ((p.x + (p.y & 1) * 3) >> 1) % 3);
output.c = ps_crt(input, ((p.x + ((p.y >> 1) & 1) * 3) >> 1) % 3);
return output;
}
static const float PI = 3.14159265359f;
PS_OUTPUT ps_filter_complex(PS_INPUT input) // triangular
{
PS_OUTPUT output;
float2 texdim;
Texture.GetDimensions(texdim.x, texdim.y);
output.c = (0.9 - 0.4 * cos(2 * PI * input.t.y * texdim.y)) * sample_c(float2(input.t.x, (floor(input.t.y * texdim.y) + 0.5) / texdim.y));
return output;
}
//Lottes CRT
#define MaskingType 4 //[1|2|3|4] The type of CRT shadow masking used. 1: compressed TV style, 2: Aperture-grille, 3: Stretched VGA style, 4: VGA style.
#define ScanBrightness -8.00 //[-16.0 to 1.0] The overall brightness of the scanline effect. Lower for darker, higher for brighter.
#define FilterCRTAmount -3.00 //[-4.0 to 1.0] The amount of filtering used, to replicate the TV CRT look. Lower for less, higher for more.
#define HorizontalWarp 0.00 //[0.0 to 0.1] The distortion warping effect for the horizontal (x) axis of the screen. Use small increments.
#define VerticalWarp 0.00 //[0.0 to 0.1] The distortion warping effect for the verticle (y) axis of the screen. Use small increments.
#define MaskAmountDark 0.50 //[0.0 to 1.0] The value of the dark masking line effect used. Lower for darker lower end masking, higher for brighter.
#define MaskAmountLight 1.50 //[0.0 to 2.0] The value of the light masking line effect used. Lower for darker higher end masking, higher for brighter.
#define BloomPixel -1.50 //[-2.0 -0.5] Pixel bloom radius. Higher for increased softness of bloom.
#define BloomScanLine -2.0 //[-4.0 -1.0] Scanline bloom radius. Higher for increased softness of bloom.
#define BloomAmount 0.15 //[0.0 1.0] Bloom intensity. Higher for brighter.
#define Shape 2.0 //[0.0 10.0] Kernal filter shape. Lower values will darken image and introduce moire patterns if used with curvature.
#define UseShadowMask 1 //[0 or 1] Enables, or disables the use of the CRT shadow mask. 0 is disabled, 1 is enabled.
float ToLinear1(float c)
{
return c <= 0.04045 ? c / 12.92 : pow((abs(c) + 0.055) / 1.055, 2.4);
}
float3 ToLinear(float3 c)
{
return float3(ToLinear1(c.r), ToLinear1(c.g), ToLinear1(c.b));
}
float ToSrgb1(float c)
{
return c < 0.0031308 ? c * 12.92 : 1.055 * pow(abs(c), 0.41666) - 0.055;
}
float3 ToSrgb(float3 c)
{
return float3(ToSrgb1(c.r), ToSrgb1(c.g), ToSrgb1(c.b));
}
float3 Fetch(float2 pos, float2 off)
{
pos = (floor(pos * u_target_size + off) + float2(0.5, 0.5)) / u_target_size;
if (max(abs(pos.x - 0.5), abs(pos.y - 0.5)) > 0.5)
{
return float3(0.0, 0.0, 0.0);
}
else
{
return ToLinear(Texture.Sample(TextureSampler, pos.xy).rgb);
}
}
float2 Dist(float2 pos)
{
pos = pos * float2(640, 480);
return -((pos - floor(pos)) - float2(0.5, 0.5));
}
float Gaus(float pos, float scale)
{
return exp2(scale * pos * pos);
}
float3 Horz3(float2 pos, float off)
{
float3 b = Fetch(pos, float2(-1.0, off));
float3 c = Fetch(pos, float2(0.0, off));
float3 d = Fetch(pos, float2(1.0, off));
float dst = Dist(pos).x;
// Convert distance to weight.
float scale = FilterCRTAmount;
float wb = Gaus(dst - 1.0, scale);
float wc = Gaus(dst + 0.0, scale);
float wd = Gaus(dst + 1.0, scale);
return (b * wb + c * wc + d * wd) / (wb + wc + wd);
}
float3 Horz5(float2 pos, float off)
{
float3 a = Fetch(pos, float2(-2.0, off));
float3 b = Fetch(pos, float2(-1.0, off));
float3 c = Fetch(pos, float2(0.0, off));
float3 d = Fetch(pos, float2(1.0, off));
float3 e = Fetch(pos, float2(2.0, off));
float dst = Dist(pos).x;
// Convert distance to weight.
float scale = FilterCRTAmount;
float wa = Gaus(dst - 2.0, scale);
float wb = Gaus(dst - 1.0, scale);
float wc = Gaus(dst + 0.0, scale);
float wd = Gaus(dst + 1.0, scale);
float we = Gaus(dst + 2.0, scale);
return (a * wa + b * wb + c * wc + d * wd + e * we) / (wa + wb + wc + wd + we);
}
float3 Horz7(float2 pos, float off)
{
float3 a = Fetch(pos, float2(-3.0, off));
float3 b = Fetch(pos, float2(-2.0, off));
float3 c = Fetch(pos, float2(-1.0, off));
float3 d = Fetch(pos, float2( 0.0, off));
float3 e = Fetch(pos, float2( 1.0, off));
float3 f = Fetch(pos, float2( 2.0, off));
float3 g = Fetch(pos, float2( 3.0, off));
float dst = Dist(pos).x;
// Convert distance to weight.
float scale = BloomPixel;
float wa = Gaus(dst - 3.0, scale);
float wb = Gaus(dst - 2.0, scale);
float wc = Gaus(dst - 1.0, scale);
float wd = Gaus(dst + 0.0, scale);
float we = Gaus(dst + 1.0, scale);
float wf = Gaus(dst + 2.0, scale);
float wg = Gaus(dst + 3.0, scale);
// Return filtered sample.
return (a * wa + b * wb + c * wc + d * wd + e * we + f * wf + g * wg) / (wa + wb + wc + wd + we + wf + wg);
}
// Return scanline weight.
float Scan(float2 pos, float off)
{
float dst = Dist(pos).y;
return Gaus(dst + off, ScanBrightness);
}
float BloomScan(float2 pos, float off)
{
float dst = Dist(pos).y;
return Gaus(dst + off, BloomScanLine);
}
float3 Tri(float2 pos)
{
float3 a = Horz3(pos, -1.0);
float3 b = Horz5(pos, 0.0);
float3 c = Horz3(pos, 1.0);
float wa = Scan(pos, -1.0);
float wb = Scan(pos, 0.0);
float wc = Scan(pos, 1.0);
return (a * wa) + (b * wb) + (c * wc);
}
float3 Bloom(float2 pos)
{
float3 a = Horz5(pos,-2.0);
float3 b = Horz7(pos,-1.0);
float3 c = Horz7(pos, 0.0);
float3 d = Horz7(pos, 1.0);
float3 e = Horz5(pos, 2.0);
float wa = BloomScan(pos,-2.0);
float wb = BloomScan(pos,-1.0);
float wc = BloomScan(pos, 0.0);
float wd = BloomScan(pos, 1.0);
float we = BloomScan(pos, 2.0);
return a * wa + b * wb + c * wc + d * wd + e * we;
}
float2 Warp(float2 pos)
{
pos = pos * 2.0 - 1.0;
pos *= float2(1.0 + (pos.y * pos.y) * HorizontalWarp, 1.0 + (pos.x * pos.x) * VerticalWarp);
return pos * 0.5 + 0.5;
}
float3 Mask(float2 pos)
{
#if MaskingType == 1
// Very compressed TV style shadow mask.
float lines = MaskAmountLight;
float odd = 0.0;
if (frac(pos.x / 6.0) < 0.5)
{
odd = 1.0;
}
if (frac((pos.y + odd) / 2.0) < 0.5)
{
lines = MaskAmountDark;
}
pos.x = frac(pos.x / 3.0);
float3 mask = float3(MaskAmountDark, MaskAmountDark, MaskAmountDark);
if (pos.x < 0.333)
{
mask.r = MaskAmountLight;
}
else if (pos.x < 0.666)
{
mask.g = MaskAmountLight;
}
else
{
mask.b = MaskAmountLight;
}
mask *= lines;
return mask;
#elif MaskingType == 2
// Aperture-grille.
pos.x = frac(pos.x / 3.0);
float3 mask = float3(MaskAmountDark, MaskAmountDark, MaskAmountDark);
if (pos.x < 0.333)
{
mask.r = MaskAmountLight;
}
else if (pos.x < 0.666)
{
mask.g = MaskAmountLight;
}
else
{
mask.b = MaskAmountLight;
}
return mask;
#elif MaskingType == 3
// Stretched VGA style shadow mask (same as prior shaders).
pos.x += pos.y * 3.0;
float3 mask = float3(MaskAmountDark, MaskAmountDark, MaskAmountDark);
pos.x = frac(pos.x / 6.0);
if (pos.x < 0.333)
{
mask.r = MaskAmountLight;
}
else if (pos.x < 0.666)
{
mask.g = MaskAmountLight;
}
else
{
mask.b = MaskAmountLight;
}
return mask;
#else
// VGA style shadow mask.
pos.xy = floor(pos.xy * float2(1.0, 0.5));
pos.x += pos.y * 3.0;
float3 mask = float3(MaskAmountDark, MaskAmountDark, MaskAmountDark);
pos.x = frac(pos.x / 6.0);
if (pos.x < 0.333)
{
mask.r = MaskAmountLight;
}
else if (pos.x < 0.666)
{
mask.g = MaskAmountLight;
}
else
{
mask.b = MaskAmountLight;
}
return mask;
#endif
}
float4 LottesCRTPass(float4 fragcoord)
{
float4 color;
fragcoord -= u_target_rect;
float2 inSize = u_target_resolution - (2 * u_target_rect.xy);
float2 pos = Warp(fragcoord.xy / inSize);
color.rgb = Tri(pos);
color.rgb += Bloom(pos) * BloomAmount;
#if UseShadowMask
color.rgb *= Mask(fragcoord.xy);
#endif
color.rgb = ToSrgb(color.rgb);
color.a = 1.0;
return color;
}
PS_OUTPUT ps_filter_lottes(PS_INPUT input)
{
PS_OUTPUT output;
output.c = LottesCRTPass(input.p);
return output;
}
PS_OUTPUT ps_4x_rgss(PS_INPUT input)
{
PS_OUTPUT output;
float2 dxy = float2(ddx(input.t.x), ddy(input.t.y));
float3 color = 0;
float s = 1.0/8.0;
float l = 3.0/8.0;
color += sample_c(input.t + float2( s, l) * dxy).rgb;
color += sample_c(input.t + float2( l,-s) * dxy).rgb;
color += sample_c(input.t + float2(-s,-l) * dxy).rgb;
color += sample_c(input.t + float2(-l, s) * dxy).rgb;
output.c = float4(color * 0.25,1);
return output;
}
PS_OUTPUT ps_automagical_supersampling(PS_INPUT input)
{
PS_OUTPUT output;
float2 ratio = (u_source_size / u_target_size) * 0.5;
float2 steps = floor(ratio);
float3 col = sample_c(input.t).rgb;
float div = 1;
for (float y = 0; y < steps.y; y++)
{
for (float x = 0; x < steps.x; x++)
{
float2 offset = float2(x,y) - ratio * 0.5;
col += sample_c(input.t + offset * u_rcp_source_resolution * 2.0).rgb;
div++;
}
}
output.c = float4(col / div, 1);
return output;
}
@@ -1,52 +0,0 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
Texture2D Texture;
SamplerState Sampler;
cbuffer cb0
{
float4 params;
};
/*
** Contrast, saturation, brightness
** Code of this function is from TGM's shader pack
** http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=21057
*/
// For all settings: 1.0 = 100% 0.5=50% 1.5 = 150%
float4 ContrastSaturationBrightness(float4 color) // Ported to HLSL
{
float brt = params.x;
float con = params.y;
float sat = params.z;
// Increase or decrease these values to adjust r, g and b color channels separately
const float AvgLumR = 0.5;
const float AvgLumG = 0.5;
const float AvgLumB = 0.5;
const float3 LumCoeff = float3(0.2125, 0.7154, 0.0721);
float3 AvgLumin = float3(AvgLumR, AvgLumG, AvgLumB);
float3 brtColor = color.rgb * brt;
float3 intensity = dot(brtColor, LumCoeff);
float3 satColor = lerp(intensity, brtColor, sat);
float3 conColor = lerp(AvgLumin, satColor, con);
color.rgb = conColor;
return color;
}
struct PS_INPUT
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
};
float4 ps_main(PS_INPUT input) : SV_Target0
{
float4 c = Texture.Sample(Sampler, input.t);
return ContrastSaturationBrightness(c);
}
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More