Merge pull request #343 from PCSX2/shader-loading

GSdx ogl: external shader loading + FXAA
This commit is contained in:
Gregory Hainaut 2014-11-10 15:43:05 +01:00
commit e6e534c13a
10 changed files with 1002 additions and 2605 deletions

View File

@ -15,15 +15,61 @@
|#################################################################################| |#################################################################################|
\*===============================================================================*/ \*===============================================================================*/
#if (SHADER_MODEL <= 0x300) #ifndef SHADER_MODEL
#define GLSL 1
#else
#define GLSL 0
#endif
#if defined(SHADER_MODEL) && (SHADER_MODEL <= 0x300)
#error GSdx FX requires shader model 4.0(Direct3D10) or higher. Use GSdx DX10/11. #error GSdx FX requires shader model 4.0(Direct3D10) or higher. Use GSdx DX10/11.
#endif #endif
#ifdef SHADER_MODEL
#include "GSdx_FX_Settings.ini" #include "GSdx_FX_Settings.ini"
#endif
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
[GLOBALS|FUNCTIONS] [GLOBALS|FUNCTIONS]
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
#if (GLSL == 1)
#define int2 ivec2
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define static
#define lerp(x,y,s) mix(x,y,s)
#define saturate(x) clamp(x, 0.0, 1.0)
#define SamplerState sampler2D
struct vertex_basic
{
vec4 p;
vec2 t;
};
#ifdef ENABLE_BINDLESS_TEX
layout(bindless_sampler, location = 0) uniform sampler2D TextureSampler;
#else
layout(binding = 0) uniform sampler2D TextureSampler;
#endif
in SHADER
{
vec4 p;
vec2 t;
} PSin;
layout(location = 0) out vec4 SV_Target0;
layout(std140, binding = 14) uniform cb10
{
vec2 _xyFrame;
vec4 _rcpFrame;
};
#else
Texture2D Texture : register(t0); Texture2D Texture : register(t0);
SamplerState TextureSampler : register(s0); SamplerState TextureSampler : register(s0);
@ -50,6 +96,7 @@ struct PS_OUTPUT
{ {
float4 c : SV_Target0; float4 c : SV_Target0;
}; };
#endif
static float2 screenSize = _xyFrame; static float2 screenSize = _xyFrame;
static float2 pixelSize = _rcpFrame.xy; static float2 pixelSize = _rcpFrame.xy;
@ -61,6 +108,16 @@ float RGBLuminance(float3 color)
return dot(color.rgb, lumCoeff); return dot(color.rgb, lumCoeff);
} }
float4 sample_tex(SamplerState texSample, float2 t)
{
#if (GLSL == 1)
return texture(texSample, t);
#else
return Texture.Sample(texSample, t);
#endif
}
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
[FXAA CODE SECTION] [FXAA CODE SECTION]
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
@ -69,6 +126,8 @@ float RGBLuminance(float3 color)
#if (SHADER_MODEL >= 0x500) #if (SHADER_MODEL >= 0x500)
#define FXAA_HLSL_5 1 #define FXAA_HLSL_5 1
#define FXAA_GATHER4_ALPHA 1 #define FXAA_GATHER4_ALPHA 1
#elif (GLSL == 1)
#define FXAA_GATHER4_ALPHA 1
#else #else
#define FXAA_HLSL_4 1 #define FXAA_HLSL_4 1
#define FXAA_GATHER4_ALPHA 0 #define FXAA_GATHER4_ALPHA 0
@ -559,12 +618,12 @@ float4 SampleBiLinear(SamplerState texSample, float2 texcoord)
float2 uvCoord = float2((float(nX) + OffsetAmount) / screenSize.x, (float(nY) + OffsetAmount) / screenSize.y); float2 uvCoord = float2((float(nX) + OffsetAmount) / screenSize.x, (float(nY) + OffsetAmount) / screenSize.y);
// Take nearest two data in current row. // Take nearest two data in current row.
float4 SampleA = Texture.Sample(texSample, uvCoord); float4 SampleA = sample_tex(texSample, uvCoord);
float4 SampleB = Texture.Sample(texSample, uvCoord + float2(texelSizeX, 0.0)); float4 SampleB = sample_tex(texSample, uvCoord + float2(texelSizeX, 0.0));
// Take nearest two data in bottom row. // Take nearest two data in bottom row.
float4 SampleC = Texture.Sample(texSample, uvCoord + float2(0.0, texelSizeY)); float4 SampleC = sample_tex(texSample, uvCoord + float2(0.0, texelSizeY));
float4 SampleD = Texture.Sample(texSample, uvCoord + float2(texelSizeX, texelSizeY)); float4 SampleD = sample_tex(texSample, uvCoord + float2(texelSizeX, texelSizeY));
float LX = frac(texcoord.x * screenSize.x); //Get Interpolation factor for X direction. float LX = frac(texcoord.x * screenSize.x); //Get Interpolation factor for X direction.
@ -618,7 +677,7 @@ float4 BicubicFilter(SamplerState texSample, float2 texcoord)
{ {
for (int n = -1; n <= 2; n++) for (int n = -1; n <= 2; n++)
{ {
float4 Samples = Texture.Sample(texSample, uvCoord + float4 Samples = sample_tex(texSample, uvCoord +
float2(texelSizeX * float(m), texelSizeY * float(n))); float2(texelSizeX * float(m), texelSizeY * float(n)));
float vc1 = Interpolation(float(m) - a); float vc1 = Interpolation(float(m) - a);
@ -661,36 +720,36 @@ float4 GaussianPass(float4 color, float2 texcoord)
float2 dx2 = 2.0 * dx; float2 dx2 = 2.0 * dx;
float2 dy2 = 2.0 * dy; float2 dy2 = 2.0 * dy;
float4 gaussian = Texture.Sample(TextureSampler, texcoord); float4 gaussian = sample_tex(TextureSampler, texcoord);
gaussian += Texture.Sample(TextureSampler, texcoord - dx2 + dy2); gaussian += sample_tex(TextureSampler, texcoord - dx2 + dy2);
gaussian += Texture.Sample(TextureSampler, texcoord - dx + dy2); gaussian += sample_tex(TextureSampler, texcoord - dx + dy2);
gaussian += Texture.Sample(TextureSampler, texcoord + dy2); gaussian += sample_tex(TextureSampler, texcoord + dy2);
gaussian += Texture.Sample(TextureSampler, texcoord + dx + dy2); gaussian += sample_tex(TextureSampler, texcoord + dx + dy2);
gaussian += Texture.Sample(TextureSampler, texcoord + dx2 + dy2); gaussian += sample_tex(TextureSampler, texcoord + dx2 + dy2);
gaussian += Texture.Sample(TextureSampler, texcoord - dx2 + dy); gaussian += sample_tex(TextureSampler, texcoord - dx2 + dy);
gaussian += Texture.Sample(TextureSampler, texcoord - dx + dy); gaussian += sample_tex(TextureSampler, texcoord - dx + dy);
gaussian += Texture.Sample(TextureSampler, texcoord + dy); gaussian += sample_tex(TextureSampler, texcoord + dy);
gaussian += Texture.Sample(TextureSampler, texcoord + dx + dy); gaussian += sample_tex(TextureSampler, texcoord + dx + dy);
gaussian += Texture.Sample(TextureSampler, texcoord + dx2 + dy); gaussian += sample_tex(TextureSampler, texcoord + dx2 + dy);
gaussian += Texture.Sample(TextureSampler, texcoord - dx2); gaussian += sample_tex(TextureSampler, texcoord - dx2);
gaussian += Texture.Sample(TextureSampler, texcoord - dx); gaussian += sample_tex(TextureSampler, texcoord - dx);
gaussian += Texture.Sample(TextureSampler, texcoord + dx); gaussian += sample_tex(TextureSampler, texcoord + dx);
gaussian += Texture.Sample(TextureSampler, texcoord + dx2); gaussian += sample_tex(TextureSampler, texcoord + dx2);
gaussian += Texture.Sample(TextureSampler, texcoord - dx2 - dy); gaussian += sample_tex(TextureSampler, texcoord - dx2 - dy);
gaussian += Texture.Sample(TextureSampler, texcoord - dx - dy); gaussian += sample_tex(TextureSampler, texcoord - dx - dy);
gaussian += Texture.Sample(TextureSampler, texcoord - dy); gaussian += sample_tex(TextureSampler, texcoord - dy);
gaussian += Texture.Sample(TextureSampler, texcoord + dx - dy); gaussian += sample_tex(TextureSampler, texcoord + dx - dy);
gaussian += Texture.Sample(TextureSampler, texcoord + dx2 - dy); gaussian += sample_tex(TextureSampler, texcoord + dx2 - dy);
gaussian += Texture.Sample(TextureSampler, texcoord - dx2 - dy2); gaussian += sample_tex(TextureSampler, texcoord - dx2 - dy2);
gaussian += Texture.Sample(TextureSampler, texcoord - dx - dy2); gaussian += sample_tex(TextureSampler, texcoord - dx - dy2);
gaussian += Texture.Sample(TextureSampler, texcoord - dy2); gaussian += sample_tex(TextureSampler, texcoord - dy2);
gaussian += Texture.Sample(TextureSampler, texcoord + dx - dy2); gaussian += sample_tex(TextureSampler, texcoord + dx - dy2);
gaussian += Texture.Sample(TextureSampler, texcoord + dx2 - dy2); gaussian += sample_tex(TextureSampler, texcoord + dx2 - dy2);
gaussian /= 25.0; gaussian /= 25.0;
@ -739,10 +798,10 @@ float4 BicubicScalar(in SamplerState tex, in float2 uv, in float2 texSize)
coord01 = (coord01 + 0.5) * rec_nrCP; coord01 = (coord01 + 0.5) * rec_nrCP;
coord11 = (coord11 + 0.5) * rec_nrCP; coord11 = (coord11 + 0.5) * rec_nrCP;
float4 tex00 = Texture.SampleLevel(tex, coord00, 0); float4 tex00 = sample_texLevel(tex, coord00, 0);
float4 tex10 = Texture.SampleLevel(tex, coord10, 0); float4 tex10 = sample_texLevel(tex, coord10, 0);
float4 tex01 = Texture.SampleLevel(tex, coord01, 0); float4 tex01 = sample_texLevel(tex, coord01, 0);
float4 tex11 = Texture.SampleLevel(tex, coord11, 0); float4 tex11 = sample_texLevel(tex, coord11, 0);
tex00 = lerp(tex01, tex00, float4(g0.y, g0.y, g0.y, g0.y)); tex00 = lerp(tex01, tex00, float4(g0.y, g0.y, g0.y, g0.y));
tex10 = lerp(tex11, tex10, float4(g0.y, g0.y, g0.y, g0.y)); tex10 = lerp(tex11, tex10, float4(g0.y, g0.y, g0.y, g0.y));
@ -765,7 +824,7 @@ float4 BiCubicScalarPass(float4 color, float2 texcoord)
#if (LANCZOS_SCALAR == 1) #if (LANCZOS_SCALAR == 1)
float3 pixel(float xpos, float ypos) float3 pixel(float xpos, float ypos)
{ {
return Texture.Sample(TextureSampler, float2(xpos, ypos)).rgb; return sample_tex(TextureSampler, float2(xpos, ypos)).rgb;
} }
float3 line_run(float ypos, float4 xpos, float4 linetaps) float3 line_run(float ypos, float4 xpos, float4 linetaps)
@ -882,7 +941,7 @@ float4 SampleBicubic(in SamplerState texSample, in float2 texcoord)
{ {
for (int n = -1; n <= 2; n++) for (int n = -1; n <= 2; n++)
{ {
float4 Samples = Texture.Sample(texSample, uvCoord + float4 Samples = sample_tex(texSample, uvCoord +
float2(texelSizeX * float(m), texelSizeY * float(n))); float2(texelSizeX * float(m), texelSizeY * float(n)));
float vc1 = Cubic(float(m) - a); float vc1 = Cubic(float(m) - a);
@ -943,7 +1002,6 @@ float4 VibrancePass(float4 color, float2 texcoord)
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
[BLENDED BLOOM CODE SECTION] [BLENDED BLOOM CODE SECTION]
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
#if (BLENDED_BLOOM == 1) #if (BLENDED_BLOOM == 1)
float3 BlendAddLight(float3 color, float3 bloom) float3 BlendAddLight(float3 color, float3 bloom)
{ {
@ -978,10 +1036,10 @@ float3 BlendOverlay(float3 color, float3 bloom)
float4 PyramidFilter(SamplerState tex, float2 texcoord, float2 width) float4 PyramidFilter(SamplerState tex, float2 texcoord, float2 width)
{ {
float4 color = Texture.Sample(tex, texcoord + float2(0.5, 0.5) * width); float4 color = sample_tex(tex, texcoord + float2(0.5, 0.5) * width);
color += Texture.Sample(tex, texcoord + float2(-0.5, 0.5) * width); color += sample_tex(tex, texcoord + float2(-0.5, 0.5) * width);
color += Texture.Sample(tex, texcoord + float2(0.5, -0.5) * width); color += sample_tex(tex, texcoord + float2(0.5, -0.5) * width);
color += Texture.Sample(tex, texcoord + float2(-0.5, -0.5) * width); color += sample_tex(tex, texcoord + float2(-0.5, -0.5) * width);
color *= 0.25; color *= 0.25;
return color; return color;
@ -1013,34 +1071,34 @@ float4 BloomPass(float4 color, float2 texcoord)
float4 bloomBlend = bloom * 0.22520613262190495; float4 bloomBlend = bloom * 0.22520613262190495;
bloomBlend += 0.002589001911021066 * Texture.Sample(TextureSampler, texcoord - dx2 + dy2); bloomBlend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord - dx2 + dy2);
bloomBlend += 0.010778807494659370 * Texture.Sample(TextureSampler, texcoord - dx + dy2); bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - dx + dy2);
bloomBlend += 0.024146616900339800 * Texture.Sample(TextureSampler, texcoord + dy2); bloomBlend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord + dy2);
bloomBlend += 0.010778807494659370 * Texture.Sample(TextureSampler, texcoord + dx + dy2); bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + dx + dy2);
bloomBlend += 0.002589001911021066 * Texture.Sample(TextureSampler, texcoord + dx2 + dy2); bloomBlend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord + dx2 + dy2);
bloomBlend += 0.010778807494659370 * Texture.Sample(TextureSampler, texcoord - dx2 + dy); bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - dx2 + dy);
bloomBlend += 0.044875475183061630 * Texture.Sample(TextureSampler, texcoord - dx + dy); bloomBlend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord - dx + dy);
bloomBlend += 0.100529757860782610 * Texture.Sample(TextureSampler, texcoord + dy); bloomBlend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord + dy);
bloomBlend += 0.044875475183061630 * Texture.Sample(TextureSampler, texcoord + dx + dy); bloomBlend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord + dx + dy);
bloomBlend += 0.010778807494659370 * Texture.Sample(TextureSampler, texcoord + dx2 + dy); bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + dx2 + dy);
bloomBlend += 0.024146616900339800 * Texture.Sample(TextureSampler, texcoord - dx2); bloomBlend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord - dx2);
bloomBlend += 0.100529757860782610 * Texture.Sample(TextureSampler, texcoord - dx); bloomBlend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord - dx);
bloomBlend += 0.100529757860782610 * Texture.Sample(TextureSampler, texcoord + dx); bloomBlend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord + dx);
bloomBlend += 0.024146616900339800 * Texture.Sample(TextureSampler, texcoord + dx2); bloomBlend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord + dx2);
bloomBlend += 0.010778807494659370 * Texture.Sample(TextureSampler, texcoord - dx2 - dy); bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - dx2 - dy);
bloomBlend += 0.044875475183061630 * Texture.Sample(TextureSampler, texcoord - dx - dy); bloomBlend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord - dx - dy);
bloomBlend += 0.100529757860782610 * Texture.Sample(TextureSampler, texcoord - dy); bloomBlend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord - dy);
bloomBlend += 0.044875475183061630 * Texture.Sample(TextureSampler, texcoord + dx - dy); bloomBlend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord + dx - dy);
bloomBlend += 0.010778807494659370 * Texture.Sample(TextureSampler, texcoord + dx2 - dy); bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + dx2 - dy);
bloomBlend += 0.002589001911021066 * Texture.Sample(TextureSampler, texcoord - dx2 - dy2); bloomBlend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord - dx2 - dy2);
bloomBlend += 0.010778807494659370 * Texture.Sample(TextureSampler, texcoord - dx - dy2); bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - dx - dy2);
bloomBlend += 0.024146616900339800 * Texture.Sample(TextureSampler, texcoord - dy2); bloomBlend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord - dy2);
bloomBlend += 0.010778807494659370 * Texture.Sample(TextureSampler, texcoord + dx - dy2); bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + dx - dy2);
bloomBlend += 0.002589001911021066 * Texture.Sample(TextureSampler, texcoord + dx2 - dy2); bloomBlend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord + dx2 - dy2);
bloomBlend = lerp(color, bloomBlend, float(BlendStrength)); bloomBlend = lerp(color, bloomBlend, float(BlendStrength));
bloom.rgb = BloomType(bloom.rgb, bloomBlend.rgb); bloom.rgb = BloomType(bloom.rgb, bloomBlend.rgb);
@ -1054,7 +1112,6 @@ float4 BloomPass(float4 color, float2 texcoord)
return color; return color;
} }
#endif #endif
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
[COLOR CORRECTION/TONE MAPPING CODE SECTION] [COLOR CORRECTION/TONE MAPPING CODE SECTION]
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
@ -1072,7 +1129,7 @@ float3 FilmicTonemap(float3 color)
float W = float(WhitePoint); float W = float(WhitePoint);
float3 numerator = ((Q*(A*Q + C*B) + D*E) / (Q*(A*Q + B) + D*F)) - E / F; float3 numerator = ((Q*(A*Q + C*B) + D*E) / (Q*(A*Q + B) + D*F)) - E / F;
float3 denominator = ((W*(A*W + C*B) + D*E) / (W*(A*W + B) + D*F)) - E / F; float denominator = ((W*(A*W + C*B) + D*E) / (W*(A*W + B) + D*F)) - E / F;
color.xyz = numerator / denominator; color.xyz = numerator / denominator;
@ -1088,8 +1145,14 @@ float3 ColorShift(float3 color)
colMood.b = float(BlueShift); colMood.b = float(BlueShift);
float fLum = RGBLuminance(color.rgb); float fLum = RGBLuminance(color.rgb);
#if (GLSL == 1)
// Is HLSL float3(x) equivalent to float3(x,x,x) ?
colMood = lerp(float3(0.0), colMood, saturate(fLum * 2.0));
colMood = lerp(colMood, float3(1.0), saturate(fLum - 0.5) * 2.0);
#else
colMood = lerp(0.0, colMood, saturate(fLum * 2.0)); colMood = lerp(0.0, colMood, saturate(fLum * 2.0));
colMood = lerp(colMood, 1.0, saturate(fLum - 0.5) * 2.0); colMood = lerp(colMood, 1.0, saturate(fLum - 0.5) * 2.0);
#endif
float3 colOutput = lerp(color, colMood, saturate(fLum * float(ShiftRatio))); float3 colOutput = lerp(color, colMood, saturate(fLum * float(ShiftRatio)));
return colOutput; return colOutput;
@ -1108,7 +1171,11 @@ float3 ColorCorrection(float3 color)
return saturate(color); return saturate(color);
} }
#if (GLSL == 1)
float4 TonemapPass(float4 color, float2 texcoord)
#else
float4 TonemapPass(float4 color, float2 texcoord) : COLOR0 float4 TonemapPass(float4 color, float2 texcoord) : COLOR0
#endif
{ {
const float delta = 0.001f; const float delta = 0.001f;
const float wpoint = pow(1.002f, 2.0f); const float wpoint = pow(1.002f, 2.0f);
@ -1118,11 +1185,24 @@ float4 TonemapPass(float4 color, float2 texcoord) : COLOR0
if (FilmicProcess == 0) { color.rgb = FilmicTonemap(color.rgb); } if (FilmicProcess == 0) { color.rgb = FilmicTonemap(color.rgb); }
// RGB -> XYZ conversion // RGB -> XYZ conversion
#if (GLSL == 1)
// GLSL is column major whereas HLSL is row major ...
const mat3 RGB2XYZ = mat3 (
0.4124564, 0.2126729, 0.0193339, // first column (not row)
0.3575761, 0.7151522, 0.1191920, // 2nd column
0.1804375, 0.0721750, 0.9503041 // 3rd column
);
#else
const float3x3 RGB2XYZ = { 0.4124564, 0.3575761, 0.1804375, const float3x3 RGB2XYZ = { 0.4124564, 0.3575761, 0.1804375,
0.2126729, 0.7151522, 0.0721750, 0.2126729, 0.7151522, 0.0721750,
0.0193339, 0.1191920, 0.9503041 }; 0.0193339, 0.1191920, 0.9503041 };
#endif
#if (GLSL == 1)
float3 XYZ = RGB2XYZ * color.rgb;
#else
float3 XYZ = mul(RGB2XYZ, color.rgb); float3 XYZ = mul(RGB2XYZ, color.rgb);
#endif
// XYZ -> Yxy conversion // XYZ -> Yxy conversion
float3 Yxy; float3 Yxy;
@ -1154,11 +1234,24 @@ float4 TonemapPass(float4 color, float2 texcoord) : COLOR0
if (CorrectionPalette == 3) { XYZ.rgb = ColorCorrection(XYZ.rgb); } if (CorrectionPalette == 3) { XYZ.rgb = ColorCorrection(XYZ.rgb); }
// XYZ -> RGB conversion // XYZ -> RGB conversion
#if (GLSL == 1)
// GLSL is column major whereas HLSL is row major ...
const mat3 XYZ2RGB = mat3 (
3.2404542, -0.9692660, 0.0556434, // first column (not row)
-1.5371385, 1.8760108, -0.2040259, // 2nd column
-0.4985314, 0.0415560, 1.0572252 // 3rd column
);
#else
const float3x3 XYZ2RGB = { 3.2404542,-1.5371385,-0.4985314, const float3x3 XYZ2RGB = { 3.2404542,-1.5371385,-0.4985314,
-0.9692660, 1.8760108, 0.0415560, -0.9692660, 1.8760108, 0.0415560,
0.0556434,-0.2040259, 1.0572252 }; 0.0556434,-0.2040259, 1.0572252 };
#endif
#if (GLSL == 1)
color.rgb = XYZ2RGB * XYZ;
#else
color.rgb = mul(XYZ2RGB, XYZ); color.rgb = mul(XYZ2RGB, XYZ);
#endif
color.a = RGBLuminance(color.rgb); color.a = RGBLuminance(color.rgb);
return saturate(color); return saturate(color);
@ -1298,7 +1391,7 @@ float4 CelPass(float4 color, float2 texcoord)
for (int i = 0; i < NUM; i++) for (int i = 0; i < NUM; i++)
{ {
col[i] = Texture.Sample(TextureSampler, texcoord + c[i] * RoundingOffset).rgb; col[i] = sample_tex(TextureSampler, texcoord + c[i] * RoundingOffset).rgb;
#if (ColorRounding == 1) #if (ColorRounding == 1)
col[i].r = saturate(round(col[i].r * thresholds.r) / thresholds.r); col[i].r = saturate(round(col[i].r * thresholds.r) / thresholds.r);
@ -1320,11 +1413,11 @@ float4 CelPass(float4 color, float2 texcoord)
float3 shadedColor = (sum / NUM); float3 shadedColor = (sum / NUM);
float edgeX = dot(Texture.Sample(TextureSampler, texcoord + pixel).rgb, celLumaCoef); float edgeX = dot(sample_tex(TextureSampler, texcoord + pixel).rgb, celLumaCoef);
edgeX = dot(float4(Texture.Sample(TextureSampler, texcoord - pixel).rgb, edgeX), float4(celLumaCoef, -1.0)); edgeX = dot(float4(sample_tex(TextureSampler, texcoord - pixel).rgb, edgeX), float4(celLumaCoef, -1.0));
float edgeY = dot(Texture.Sample(TextureSampler, texcoord + float2(pixel.x, -pixel.y)).rgb, celLumaCoef); float edgeY = dot(sample_tex(TextureSampler, texcoord + float2(pixel.x, -pixel.y)).rgb, celLumaCoef);
edgeY = dot(float4(Texture.Sample(TextureSampler, texcoord + float2(-pixel.x, pixel.y)).rgb, edgeY), float4(celLumaCoef, -1.0)); edgeY = dot(float4(sample_tex(TextureSampler, texcoord + float2(-pixel.x, pixel.y)).rgb, edgeY), float4(celLumaCoef, -1.0));
float edge = dot(float2(edgeX, edgeY), float2(edgeX, edgeY)); float edge = dot(float2(edgeX, edgeY), float2(edgeX, edgeY));
@ -1570,7 +1663,13 @@ float4 BorderPass(float4 colorInput, float2 tex)
float2 border = (_rcpFrame.xy * BorderWidth); float2 border = (_rcpFrame.xy * BorderWidth);
float2 within_border = saturate((-tex * tex + tex) - (-border * border + border)); float2 within_border = saturate((-tex * tex + tex) - (-border * border + border));
#if (GLSL == 1)
// FIXME GLSL any only support bvec so try to mix it with notEqual
bvec2 cond = notEqual( within_border, vec2(0.0f) );
colorInput.rgb = all(cond) ? colorInput.rgb : border_color_float; //
#else
colorInput.rgb = all(within_border) ? colorInput.rgb : border_color_float; // colorInput.rgb = all(within_border) ? colorInput.rgb : border_color_float; //
#endif
return colorInput; return colorInput;
@ -1580,12 +1679,21 @@ float4 BorderPass(float4 colorInput, float2 tex)
[MAIN() & COMBINE PASS CODE SECTION] [MAIN() & COMBINE PASS CODE SECTION]
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
#if (GLSL == 1)
void ps_main()
#else
PS_OUTPUT ps_main(VS_OUTPUT input) PS_OUTPUT ps_main(VS_OUTPUT input)
#endif
{ {
#if (GLSL == 1)
float2 texcoord = PSin.t;
float4 color = texture(TextureSampler, texcoord);
#else
PS_OUTPUT output; PS_OUTPUT output;
float2 texcoord = input.t; float2 texcoord = input.t;
float4 color = Texture.Sample(TextureSampler, texcoord); float4 color = sample_tex(TextureSampler, texcoord);
#endif
#if (BILINEAR_FILTERING == 1) #if (BILINEAR_FILTERING == 1)
color = BiLinearPass(color, texcoord); color = BiLinearPass(color, texcoord);
@ -1659,7 +1767,11 @@ PS_OUTPUT ps_main(VS_OUTPUT input)
color = BorderPass(color, texcoord); color = BorderPass(color, texcoord);
#endif #endif
#if (GLSL == 1)
SV_Target0 = color;
#else
output.c = color; output.c = color;
return output; return output;
#endif
} }

View File

@ -34,8 +34,7 @@ eval {
print "Disable MD5\n"; print "Disable MD5\n";
}; };
# Keep the old FXAA for now my @gsdx_res = qw/convert.glsl interlace.glsl merge.glsl shadeboost.glsl tfx.glsl fxaa.fx/;
my @gsdx_res = qw/convert.glsl interlace.glsl merge.glsl shadeboost.glsl tfx.glsl old_fxaa.fx/;
my $gsdx_path = File::Spec->catdir(dirname(abs_path($0)), "..", "plugins", "GSdx", "res"); my $gsdx_path = File::Spec->catdir(dirname(abs_path($0)), "..", "plugins", "GSdx", "res");
my $gsdx_out = File::Spec->catdir($gsdx_path, "glsl_source.h"); my $gsdx_out = File::Spec->catdir($gsdx_path, "glsl_source.h");
glsl2h($gsdx_path, $gsdx_out, \@gsdx_res); glsl2h($gsdx_path, $gsdx_out, \@gsdx_res);

View File

@ -22,6 +22,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "GSDeviceOGL.h" #include "GSDeviceOGL.h"
#include "GLState.h" #include "GLState.h"
#include <fstream>
#include "res/glsl_source.h" #include "res/glsl_source.h"
@ -39,7 +40,7 @@ uint32 g_vertex_upload_byte = 0;
static const uint32 g_merge_cb_index = 10; static const uint32 g_merge_cb_index = 10;
static const uint32 g_interlace_cb_index = 11; static const uint32 g_interlace_cb_index = 11;
static const uint32 g_shadeboost_cb_index = 12; static const uint32 g_shadeboost_cb_index = 12;
static const uint32 g_fxaa_cb_index = 13; static const uint32 g_fx_cb_index = 14;
GSDeviceOGL::GSDeviceOGL() GSDeviceOGL::GSDeviceOGL()
: m_free_window(false) : m_free_window(false)
@ -52,6 +53,8 @@ GSDeviceOGL::GSDeviceOGL()
memset(&m_merge_obj, 0, sizeof(m_merge_obj)); memset(&m_merge_obj, 0, sizeof(m_merge_obj));
memset(&m_interlace, 0, sizeof(m_interlace)); memset(&m_interlace, 0, sizeof(m_interlace));
memset(&m_convert, 0, sizeof(m_convert)); memset(&m_convert, 0, sizeof(m_convert));
memset(&m_fxaa, 0, sizeof(m_fxaa));
memset(&m_shaderfx, 0, sizeof(m_shaderfx));
memset(&m_date, 0, sizeof(m_date)); memset(&m_date, 0, sizeof(m_date));
memset(&m_state, 0, sizeof(m_state)); memset(&m_state, 0, sizeof(m_state));
GLState::Clear(); GLState::Clear();
@ -94,6 +97,10 @@ GSDeviceOGL::~GSDeviceOGL()
delete m_fxaa.cb; delete m_fxaa.cb;
m_shader->Delete(m_fxaa.ps); m_shader->Delete(m_fxaa.ps);
// Clean m_shaderfx
delete m_shaderfx.cb;
m_shader->Delete(m_shaderfx.ps);
// Clean m_date // Clean m_date
delete m_date.dss; delete m_date.dss;
delete m_date.bs; delete m_date.bs;
@ -296,18 +303,6 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
rd.AntialiasedLineEnable = false; rd.AntialiasedLineEnable = false;
#endif #endif
// ****************************************************************
// fxaa
// ****************************************************************
std::string fxaa_macro = "#define FXAA_GLSL_130 1\n";
if (GLLoader::found_GL_ARB_gpu_shader5) {
// This extension become core on openGL4
fxaa_macro += "#extension GL_ARB_gpu_shader5 : enable\n";
fxaa_macro += "#define FXAA_GATHER4_ALPHA 1\n";
}
m_fxaa.cb = new GSUniformBufferOGL(g_fxaa_cb_index, sizeof(FXAAConstantBuffer));
m_fxaa.ps = m_shader->Compile("fxaa.fx", "ps_main", GL_FRAGMENT_SHADER, old_fxaa_fx, fxaa_macro);
// **************************************************************** // ****************************************************************
// DATE // DATE
// **************************************************************** // ****************************************************************
@ -920,20 +915,62 @@ void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool lin
void GSDeviceOGL::DoFXAA(GSTexture* st, GSTexture* dt) void GSDeviceOGL::DoFXAA(GSTexture* st, GSTexture* dt)
{ {
// Lazy compile
if (!m_fxaa.ps) {
std::string fxaa_macro = "#define FXAA_GLSL_130 1\n";
if (GLLoader::found_GL_ARB_gpu_shader5) { // GL4.0 extension
// Hardcoded in the new shader
//fxaa_macro += "#define FXAA_GATHER4_ALPHA 1\n";
fxaa_macro += "#extension GL_ARB_gpu_shader5 : enable\n";
} else {
fprintf(stderr, "FXAA requires the GL_ARB_gpu_shader5 extension. Please either disable FXAA or upgrade your GPU/driver.\n");
return;
}
m_fxaa.ps = m_shader->Compile("fxaa.fx", "ps_main", GL_FRAGMENT_SHADER, fxaa_fx, fxaa_macro);
}
GSVector2i s = dt->GetSize(); GSVector2i s = dt->GetSize();
GSVector4 sr(0, 0, 1, 1); GSVector4 sr(0, 0, 1, 1);
GSVector4 dr(0, 0, s.x, s.y); GSVector4 dr(0, 0, s.x, s.y);
FXAAConstantBuffer cb; StretchRect(st, sr, dt, dr, m_fxaa.ps, true);
}
// FIXME optimize: remove rcpFrameOpt. And reduce rcpFrame to vec2 void GSDeviceOGL::DoExternalFX(GSTexture* st, GSTexture* dt)
{
// Lazy compile
if (!m_shaderfx.ps) {
std::ifstream fconfig(theApp.GetConfig("shaderfx_conf", "dummy.ini"));
std::stringstream config;
if (fconfig.good())
config << fconfig.rdbuf();
std::ifstream fshader(theApp.GetConfig("shaderfx_glsl", "dummy.glsl"));
std::stringstream shader;
if (!fshader.good())
return;
shader << fshader.rdbuf();
m_shaderfx.cb = new GSUniformBufferOGL(g_fx_cb_index, sizeof(ExternalFXConstantBuffer));
m_shaderfx.ps = m_shader->Compile("Extra", "ps_main", GL_FRAGMENT_SHADER, shader.str().c_str(), config.str());
}
GSVector2i s = dt->GetSize();
GSVector4 sr(0, 0, 1, 1);
GSVector4 dr(0, 0, s.x, s.y);
ExternalFXConstantBuffer cb;
cb.xyFrame = GSVector2(s.x, s.y);
cb.rcpFrame = GSVector4(1.0f / s.x, 1.0f / s.y, 0.0f, 0.0f); cb.rcpFrame = GSVector4(1.0f / s.x, 1.0f / s.y, 0.0f, 0.0f);
cb.rcpFrameOpt = GSVector4::zero(); cb.rcpFrameOpt = GSVector4::zero();
m_fxaa.cb->upload(&cb); m_shaderfx.cb->upload(&cb);
StretchRect(st, sr, dt, dr, m_fxaa.ps, true); StretchRect(st, sr, dt, dr, m_shaderfx.ps, true);
} }
void GSDeviceOGL::DoShadeBoost(GSTexture* st, GSTexture* dt) void GSDeviceOGL::DoShadeBoost(GSTexture* st, GSTexture* dt)

View File

@ -494,6 +494,11 @@ class GSDeviceOGL : public GSDevice
GSUniformBufferOGL *cb; GSUniformBufferOGL *cb;
} m_fxaa; } m_fxaa;
struct {
GLuint ps;
GSUniformBufferOGL* cb;
} m_shaderfx;
struct { struct {
GSDepthStencilOGL* dss; GSDepthStencilOGL* dss;
GSBlendStateOGL* bs; GSBlendStateOGL* bs;
@ -535,6 +540,7 @@ class GSDeviceOGL : public GSDevice
void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0); void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0);
void DoFXAA(GSTexture* st, GSTexture* dt); void DoFXAA(GSTexture* st, GSTexture* dt);
void DoShadeBoost(GSTexture* st, GSTexture* dt); void DoShadeBoost(GSTexture* st, GSTexture* dt);
void DoExternalFX(GSTexture* st, GSTexture* dt);
void OMAttachRt(GLuint rt); void OMAttachRt(GLuint rt);
void OMAttachDs(GLuint ds); void OMAttachDs(GLuint ds);

View File

@ -24,16 +24,11 @@
#include "GSdx.h" #include "GSdx.h"
#include "GSLinuxLogo.h" #include "GSLinuxLogo.h"
GtkWidget *fsaa_combo_box, *render_combo_box, *filter_combo_box;
GtkWidget *shadeboost_check, *paltex_check, *fba_check, *aa_check, *native_res_check, *fxaa_check;
GtkWidget *sb_contrast, *sb_brightness, *sb_saturation;
GtkWidget *resx_spin, *resy_spin;
GtkWidget* CreateRenderComboBox() GtkWidget* CreateRenderComboBox()
{ {
GtkWidget *render_combo_box; GtkWidget *render_combo_box;
int renderer_box_position = 0; int renderer_box_position = 0;
render_combo_box = gtk_combo_box_new_text (); render_combo_box = gtk_combo_box_new_text ();
for(size_t i = 6; i < theApp.m_gs_renderers.size(); i++) for(size_t i = 6; i < theApp.m_gs_renderers.size(); i++)
@ -100,10 +95,10 @@ GtkWidget* CreateInterlaceComboBox()
} }
GtkWidget* CreateMsaaComboBox() GtkWidget* CreateMsaaComboBox()
{ {
GtkWidget *combo_box; GtkWidget *combo_box;
combo_box = gtk_combo_box_new_text (); combo_box = gtk_combo_box_new_text ();
// For now, let's just put in the same vaues that show up in the windows combo box. // For now, let's just put in the same vaues that show up in the windows combo box.
gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "Custom"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "Custom");
gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "2x"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "2x");
@ -120,7 +115,7 @@ GtkWidget* CreateFilterComboBox()
{ {
GtkWidget *combo_box; GtkWidget *combo_box;
combo_box = gtk_combo_box_new_text (); combo_box = gtk_combo_box_new_text ();
gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "Off"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "Off");
gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "Normal"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "Normal");
gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "Forced"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "Forced");
@ -165,7 +160,13 @@ bool RunLinuxDialog()
GtkWidget *hw_table, *shader_table, *res_frame, *hw_frame, *sw_frame, *shader_frame; GtkWidget *hw_table, *shader_table, *res_frame, *hw_frame, *sw_frame, *shader_frame;
GtkWidget *interlace_combo_box, *threads_spin; GtkWidget *interlace_combo_box, *threads_spin;
GtkWidget *interlace_label, *threads_label, *native_label, *fsaa_label, *rexy_label, *render_label, *filter_label; GtkWidget *interlace_label, *threads_label, *native_label, *fsaa_label, *rexy_label, *render_label, *filter_label;
GtkWidget *fsaa_combo_box, *render_combo_box, *filter_combo_box;
GtkWidget *shader, *shader_conf, *shader_label, *shader_conf_label;
GtkWidget *shadeboost_check, *paltex_check, *fba_check, *aa_check, *native_res_check, *fxaa_check, *shaderfx_check;
GtkWidget *sb_contrast, *sb_brightness, *sb_saturation;
GtkWidget *resx_spin, *resy_spin;
GtkWidget *hack_table, *hack_skipdraw_label, *hack_box, *hack_frame; GtkWidget *hack_table, *hack_skipdraw_label, *hack_box, *hack_frame;
GtkWidget *hack_alpha_check, *hack_date_check, *hack_offset_check, *hack_skipdraw_spin, *hack_msaa_check, *hack_sprite_check, * hack_wild_check, *hack_enble_check, *hack_logz_check; GtkWidget *hack_alpha_check, *hack_date_check, *hack_offset_check, *hack_skipdraw_spin, *hack_msaa_check, *hack_sprite_check, * hack_wild_check, *hack_enble_check, *hack_logz_check;
GtkWidget *hack_tco_label, *hack_tco_entry; GtkWidget *hack_tco_label, *hack_tco_entry;
@ -174,10 +175,10 @@ bool RunLinuxDialog()
GtkWidget *notebook, *page_label[2]; GtkWidget *notebook, *page_label[2];
int return_value; int return_value;
GdkPixbuf* logo_pixmap; GdkPixbuf* logo_pixmap;
GtkWidget *logo_image; GtkWidget *logo_image;
/* Create the widgets */ /* Create the widgets */
dialog = gtk_dialog_new_with_buttons ( dialog = gtk_dialog_new_with_buttons (
"GSdx Config", "GSdx Config",
@ -193,7 +194,7 @@ bool RunLinuxDialog()
main_box = gtk_vbox_new(false, 5); main_box = gtk_vbox_new(false, 5);
central_box = gtk_vbox_new(false, 5); central_box = gtk_vbox_new(false, 5);
advance_box = gtk_vbox_new(false, 5); advance_box = gtk_vbox_new(false, 5);
// The Internal resolution frame and container. // The Internal resolution frame and container.
res_box = gtk_vbox_new(false, 5); res_box = gtk_vbox_new(false, 5);
res_frame = gtk_frame_new ("OpenGL Internal Resolution (can cause glitches)"); res_frame = gtk_frame_new ("OpenGL Internal Resolution (can cause glitches)");
@ -203,33 +204,33 @@ bool RunLinuxDialog()
shader_box = gtk_vbox_new(false, 5); shader_box = gtk_vbox_new(false, 5);
shader_frame = gtk_frame_new("Custom Shader Settings"); shader_frame = gtk_frame_new("Custom Shader Settings");
gtk_container_add(GTK_CONTAINER(shader_frame), shader_box); gtk_container_add(GTK_CONTAINER(shader_frame), shader_box);
shader_table = gtk_table_new(5,2, false); shader_table = gtk_table_new(8,2, false);
gtk_container_add(GTK_CONTAINER(shader_box), shader_table); gtk_container_add(GTK_CONTAINER(shader_box), shader_table);
// The hardware mode frame, container, and table. // The hardware mode frame, container, and table.
hw_box = gtk_vbox_new(false, 5); hw_box = gtk_vbox_new(false, 5);
hw_frame = gtk_frame_new ("Hardware Mode Settings"); hw_frame = gtk_frame_new ("Hardware Mode Settings");
gtk_container_add(GTK_CONTAINER(hw_frame), hw_box); gtk_container_add(GTK_CONTAINER(hw_frame), hw_box);
hw_table = gtk_table_new(5,2, false); hw_table = gtk_table_new(5,2, false);
gtk_container_add(GTK_CONTAINER(hw_box), hw_table); gtk_container_add(GTK_CONTAINER(hw_box), hw_table);
// The software mode frame and container. (It doesn't have enough in it for a table.) // The software mode frame and container. (It doesn't have enough in it for a table.)
sw_box = gtk_vbox_new(false, 5); sw_box = gtk_vbox_new(false, 5);
sw_frame = gtk_frame_new ("Software Mode Settings"); sw_frame = gtk_frame_new ("Software Mode Settings");
gtk_container_add(GTK_CONTAINER(sw_frame), sw_box); gtk_container_add(GTK_CONTAINER(sw_frame), sw_box);
// The hack frame and container. // The hack frame and container.
hack_box = gtk_hbox_new(false, 5); hack_box = gtk_hbox_new(false, 5);
hack_frame = gtk_frame_new ("Hacks"); hack_frame = gtk_frame_new ("Hacks");
gtk_container_add(GTK_CONTAINER(hack_frame), hack_box); gtk_container_add(GTK_CONTAINER(hack_frame), hack_box);
hack_table = gtk_table_new(3,3, false); hack_table = gtk_table_new(3,3, false);
gtk_container_add(GTK_CONTAINER(hack_box), hack_table); gtk_container_add(GTK_CONTAINER(hack_box), hack_table);
// Grab a logo, to make things look nice. // Grab a logo, to make things look nice.
logo_pixmap = gdk_pixbuf_from_pixdata(&gsdx_ogl_logo, false, NULL); logo_pixmap = gdk_pixbuf_from_pixdata(&gsdx_ogl_logo, false, NULL);
logo_image = gtk_image_new_from_pixbuf(logo_pixmap); logo_image = gtk_image_new_from_pixbuf(logo_pixmap);
gtk_box_pack_start(GTK_BOX(main_box), logo_image, true, true, 0); gtk_box_pack_start(GTK_BOX(main_box), logo_image, true, true, 0);
// Create the renderer combo box and label, and stash them in a box. // Create the renderer combo box and label, and stash them in a box.
render_label = gtk_label_new ("Renderer:"); render_label = gtk_label_new ("Renderer:");
render_combo_box = CreateRenderComboBox(); render_combo_box = CreateRenderComboBox();
@ -237,7 +238,7 @@ bool RunLinuxDialog()
// Use gtk_box_pack_start instead of gtk_container_add so it lines up nicely. // Use gtk_box_pack_start instead of gtk_container_add so it lines up nicely.
gtk_box_pack_start(GTK_BOX(renderer_box), render_label, false, false, 5); gtk_box_pack_start(GTK_BOX(renderer_box), render_label, false, false, 5);
gtk_box_pack_start(GTK_BOX(renderer_box), render_combo_box, false, false, 5); gtk_box_pack_start(GTK_BOX(renderer_box), render_combo_box, false, false, 5);
// Create the interlace combo box and label, and stash them in a box. // Create the interlace combo box and label, and stash them in a box.
interlace_label = gtk_label_new ("Interlacing (F5):"); interlace_label = gtk_label_new ("Interlacing (F5):");
interlace_combo_box = CreateInterlaceComboBox(); interlace_combo_box = CreateInterlaceComboBox();
@ -251,7 +252,7 @@ bool RunLinuxDialog()
filter_box = gtk_hbox_new(false, 5); filter_box = gtk_hbox_new(false, 5);
gtk_box_pack_start(GTK_BOX(filter_box), filter_label, false, false, 5); gtk_box_pack_start(GTK_BOX(filter_box), filter_label, false, false, 5);
gtk_box_pack_start(GTK_BOX(filter_box), filter_combo_box, false, false, 0); gtk_box_pack_start(GTK_BOX(filter_box), filter_combo_box, false, false, 0);
// Create the threading spin box and label, and stash them in a box. (Yes, we do a lot of that.) // Create the threading spin box and label, and stash them in a box. (Yes, we do a lot of that.)
threads_label = gtk_label_new("Extra rendering threads:"); threads_label = gtk_label_new("Extra rendering threads:");
threads_spin = gtk_spin_button_new_with_range(0,100,1); threads_spin = gtk_spin_button_new_with_range(0,100,1);
@ -266,13 +267,13 @@ bool RunLinuxDialog()
native_box = gtk_hbox_new(false, 5); native_box = gtk_hbox_new(false, 5);
gtk_box_pack_start(GTK_BOX(native_box), native_label, false, false, 5); gtk_box_pack_start(GTK_BOX(native_box), native_label, false, false, 5);
gtk_box_pack_start(GTK_BOX(native_box), native_res_check, false, false, 5); gtk_box_pack_start(GTK_BOX(native_box), native_res_check, false, false, 5);
fsaa_label = gtk_label_new("Or Use Scaling:"); fsaa_label = gtk_label_new("Or Use Scaling:");
fsaa_combo_box = CreateMsaaComboBox(); fsaa_combo_box = CreateMsaaComboBox();
fsaa_box = gtk_hbox_new(false, 5); fsaa_box = gtk_hbox_new(false, 5);
gtk_box_pack_start(GTK_BOX(fsaa_box), fsaa_label, false, false, 5); gtk_box_pack_start(GTK_BOX(fsaa_box), fsaa_label, false, false, 5);
gtk_box_pack_start(GTK_BOX(fsaa_box), fsaa_combo_box, false, false, 5); gtk_box_pack_start(GTK_BOX(fsaa_box), fsaa_combo_box, false, false, 5);
rexy_label = gtk_label_new("Custom Resolution:"); rexy_label = gtk_label_new("Custom Resolution:");
resx_spin = gtk_spin_button_new_with_range(256,8192,1); resx_spin = gtk_spin_button_new_with_range(256,8192,1);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(resx_spin), theApp.GetConfig("resx", 1024)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(resx_spin), theApp.GetConfig("resx", 1024));
@ -283,6 +284,12 @@ bool RunLinuxDialog()
gtk_box_pack_start(GTK_BOX(resxy_box), resx_spin, false, false, 5); gtk_box_pack_start(GTK_BOX(resxy_box), resx_spin, false, false, 5);
gtk_box_pack_start(GTK_BOX(resxy_box), resy_spin, false, false, 5); gtk_box_pack_start(GTK_BOX(resxy_box), resy_spin, false, false, 5);
// shader fx entry
shader = gtk_file_chooser_button_new("Select an external shader", GTK_FILE_CHOOSER_ACTION_OPEN);
shader_conf = gtk_file_chooser_button_new("Then select a config", GTK_FILE_CHOOSER_ACTION_OPEN);
shader_label = gtk_label_new("External shader glsl");
shader_conf_label = gtk_label_new("External shader conf");
// Create our hack settings. // Create our hack settings.
hack_alpha_check = gtk_check_button_new_with_label("Alpha Hack"); hack_alpha_check = gtk_check_button_new_with_label("Alpha Hack");
hack_date_check = gtk_check_button_new_with_label("Date Hack"); hack_date_check = gtk_check_button_new_with_label("Date Hack");
@ -316,19 +323,21 @@ bool RunLinuxDialog()
// Create our checkboxes. // Create our checkboxes.
shadeboost_check = gtk_check_button_new_with_label("Shade boost"); shadeboost_check = gtk_check_button_new_with_label("Shade boost");
paltex_check = gtk_check_button_new_with_label("Allow 8 bits textures"); paltex_check = gtk_check_button_new_with_label("Allow 8 bits textures");
fba_check = gtk_check_button_new_with_label("Alpha correction (FBA)"); fba_check = gtk_check_button_new_with_label("Alpha correction (FBA)");
aa_check = gtk_check_button_new_with_label("Edge anti-aliasing (AA1)"); aa_check = gtk_check_button_new_with_label("Edge anti-aliasing (AA1)");
fxaa_check = gtk_check_button_new_with_label("Fxaa shader"); fxaa_check = gtk_check_button_new_with_label("Fxaa shader");
shaderfx_check = gtk_check_button_new_with_label("External shader");
// Set the checkboxes. // Set the checkboxes.
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shadeboost_check), theApp.GetConfig("shadeboost", 1)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shadeboost_check), theApp.GetConfig("shadeboost", 1));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(paltex_check), theApp.GetConfig("paltex", 0)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(paltex_check), theApp.GetConfig("paltex", 0));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fba_check), theApp.GetConfig("fba", 1)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fba_check), theApp.GetConfig("fba", 1));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(aa_check), theApp.GetConfig("aa1", 0)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(aa_check), theApp.GetConfig("aa1", 0));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxaa_check), theApp.GetConfig("fxaa", 0)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxaa_check), theApp.GetConfig("fxaa", 0));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shaderfx_check), theApp.GetConfig("shaderfx", 0));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(native_res_check), theApp.GetConfig("nativeres", 0)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(native_res_check), theApp.GetConfig("nativeres", 0));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hack_alpha_check), theApp.GetConfig("UserHacks_AlphaHack", 0)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hack_alpha_check), theApp.GetConfig("UserHacks_AlphaHack", 0));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hack_offset_check), theApp.GetConfig("UserHacks_HalfPixelOffset", 0)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hack_offset_check), theApp.GetConfig("UserHacks_HalfPixelOffset", 0));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hack_date_check), theApp.GetConfig("UserHacks_DateGL4", 0)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hack_date_check), theApp.GetConfig("UserHacks_DateGL4", 0));
@ -354,7 +363,11 @@ bool RunLinuxDialog()
GtkWidget* sb_saturation_label = gtk_label_new("Shade Boost Saturation"); GtkWidget* sb_saturation_label = gtk_label_new("Shade Boost Saturation");
gtk_scale_set_value_pos(GTK_SCALE(sb_saturation), GTK_POS_RIGHT); gtk_scale_set_value_pos(GTK_SCALE(sb_saturation), GTK_POS_RIGHT);
gtk_range_set_value(GTK_RANGE(sb_saturation), theApp.GetConfig("ShadeBoost_Saturation", 50)); gtk_range_set_value(GTK_RANGE(sb_saturation), theApp.GetConfig("ShadeBoost_Saturation", 50));
// external shader entry
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(shader), theApp.GetConfig("shaderfx_glsl", "dummy.glsl").c_str());
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(shader_conf), theApp.GetConfig("shaderfx_conf", "dummy.ini").c_str());
// Populate all those boxes we created earlier with widgets. // Populate all those boxes we created earlier with widgets.
gtk_container_add(GTK_CONTAINER(res_box), native_box); gtk_container_add(GTK_CONTAINER(res_box), native_box);
gtk_container_add(GTK_CONTAINER(res_box), fsaa_box); gtk_container_add(GTK_CONTAINER(res_box), fsaa_box);
@ -365,14 +378,19 @@ bool RunLinuxDialog()
// Tables are strange. The numbers are for their position: left, right, top, bottom. // Tables are strange. The numbers are for their position: left, right, top, bottom.
gtk_table_attach_defaults(GTK_TABLE(shader_table), fxaa_check, 0, 1, 0, 1); gtk_table_attach_defaults(GTK_TABLE(shader_table), fxaa_check, 0, 1, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(shader_table), shadeboost_check, 1, 2, 0, 1); gtk_table_attach_defaults(GTK_TABLE(shader_table), shadeboost_check, 0, 1, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_brightness_label, 0, 1, 1, 2); gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_brightness_label, 0, 1, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_brightness, 1, 2, 1, 2); gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_brightness, 1, 2, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_contrast_label, 0, 1, 2, 3); gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_contrast_label, 0, 1, 3, 4);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_contrast, 1, 2, 2, 3); gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_contrast, 1, 2, 3, 4);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_saturation_label, 0, 1, 3, 4); gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_saturation_label, 0, 1, 4, 5);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_saturation, 1, 2, 3, 4); gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_saturation, 1, 2, 4, 5);
gtk_table_attach_defaults(GTK_TABLE(shader_table), shaderfx_check, 0, 1, 5, 6);
gtk_table_attach_defaults(GTK_TABLE(shader_table), shader_label, 0, 1, 6, 7);
gtk_table_attach_defaults(GTK_TABLE(shader_table), shader, 1, 2, 6, 7);
gtk_table_attach_defaults(GTK_TABLE(shader_table), shader_conf_label, 0, 1, 7, 8);
gtk_table_attach_defaults(GTK_TABLE(shader_table), shader_conf, 1, 2, 7, 8);
// Tables are strange. The numbers are for their position: left, right, top, bottom. // Tables are strange. The numbers are for their position: left, right, top, bottom.
gtk_table_attach_defaults(GTK_TABLE(hw_table), filter_box, 0, 1, 0, 1); gtk_table_attach_defaults(GTK_TABLE(hw_table), filter_box, 0, 1, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(hw_table), paltex_check, 0, 1, 1, 2); gtk_table_attach_defaults(GTK_TABLE(hw_table), paltex_check, 0, 1, 1, 2);
@ -433,7 +451,7 @@ override_GL_ARB_shading_language_420pack = -1
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), central_box, page_label[0]); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), central_box, page_label[0]);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), advance_box, page_label[1]); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), advance_box, page_label[1]);
// Put everything in the big box. // Put everything in the big box.
gtk_container_add(GTK_CONTAINER(main_box), renderer_box); gtk_container_add(GTK_CONTAINER(main_box), renderer_box);
gtk_container_add(GTK_CONTAINER(main_box), interlace_box); gtk_container_add(GTK_CONTAINER(main_box), interlace_box);
@ -443,7 +461,7 @@ override_GL_ARB_shading_language_420pack = -1
gtk_container_add(GTK_CONTAINER(central_box), shader_frame); gtk_container_add(GTK_CONTAINER(central_box), shader_frame);
gtk_container_add(GTK_CONTAINER(central_box), hw_frame); gtk_container_add(GTK_CONTAINER(central_box), hw_frame);
gtk_container_add(GTK_CONTAINER(central_box), sw_frame); gtk_container_add(GTK_CONTAINER(central_box), sw_frame);
gtk_container_add(GTK_CONTAINER(advance_box), hack_frame); gtk_container_add(GTK_CONTAINER(advance_box), hack_frame);
gtk_container_add(GTK_CONTAINER(advance_box), gl_frame); gtk_container_add(GTK_CONTAINER(advance_box), gl_frame);
@ -455,12 +473,12 @@ override_GL_ARB_shading_language_420pack = -1
if (return_value == GTK_RESPONSE_ACCEPT) if (return_value == GTK_RESPONSE_ACCEPT)
{ {
int mode_height = 0, mode_width = 0; int mode_height = 0, mode_width = 0;
mode_width = theApp.GetConfig("ModeWidth", 640); mode_width = theApp.GetConfig("ModeWidth", 640);
mode_height = theApp.GetConfig("ModeHeight", 480); mode_height = theApp.GetConfig("ModeHeight", 480);
theApp.SetConfig("ModeHeight", mode_height); theApp.SetConfig("ModeHeight", mode_height);
theApp.SetConfig("ModeWidth", mode_width); theApp.SetConfig("ModeWidth", mode_width);
// Get all the settings from the dialog box. // Get all the settings from the dialog box.
if (gtk_combo_box_get_active(GTK_COMBO_BOX(render_combo_box)) != -1) { if (gtk_combo_box_get_active(GTK_COMBO_BOX(render_combo_box)) != -1) {
// Note the value are based on m_gs_renderers vector on GSdx.cpp // Note the value are based on m_gs_renderers vector on GSdx.cpp
@ -486,8 +504,12 @@ override_GL_ARB_shading_language_420pack = -1
theApp.SetConfig("fba", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fba_check))); theApp.SetConfig("fba", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fba_check)));
theApp.SetConfig("aa1", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(aa_check))); theApp.SetConfig("aa1", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(aa_check)));
theApp.SetConfig("fxaa", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxaa_check))); theApp.SetConfig("fxaa", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxaa_check)));
theApp.SetConfig("shaderfx", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shaderfx_check)));
theApp.SetConfig("nativeres", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(native_res_check))); theApp.SetConfig("nativeres", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(native_res_check)));
theApp.SetConfig("shaderfx_glsl", gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(shader)));
theApp.SetConfig("shaderfx_conf", gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(shader_conf)));
theApp.SetConfig("ShadeBoost_Saturation", (int)gtk_range_get_value(GTK_RANGE(sb_saturation))); theApp.SetConfig("ShadeBoost_Saturation", (int)gtk_range_get_value(GTK_RANGE(sb_saturation)));
theApp.SetConfig("ShadeBoost_Brightness", (int)gtk_range_get_value(GTK_RANGE(sb_brightness))); theApp.SetConfig("ShadeBoost_Brightness", (int)gtk_range_get_value(GTK_RANGE(sb_brightness)));
theApp.SetConfig("ShadeBoost_Contrast", (int)gtk_range_get_value(GTK_RANGE(sb_contrast))); theApp.SetConfig("ShadeBoost_Contrast", (int)gtk_range_get_value(GTK_RANGE(sb_contrast)));
@ -495,7 +517,7 @@ override_GL_ARB_shading_language_420pack = -1
theApp.SetConfig("upscale_multiplier", (int)gtk_combo_box_get_active(GTK_COMBO_BOX(fsaa_combo_box))+1); theApp.SetConfig("upscale_multiplier", (int)gtk_combo_box_get_active(GTK_COMBO_BOX(fsaa_combo_box))+1);
theApp.SetConfig("resx", (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(resx_spin))); theApp.SetConfig("resx", (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(resx_spin)));
theApp.SetConfig("resy", (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(resy_spin))); theApp.SetConfig("resy", (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(resy_spin)));
theApp.SetConfig("UserHacks_SkipDraw", (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(hack_skipdraw_spin))); theApp.SetConfig("UserHacks_SkipDraw", (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(hack_skipdraw_spin)));
theApp.SetConfig("UserHacks_HalfPixelOffset", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hack_offset_check))); theApp.SetConfig("UserHacks_HalfPixelOffset", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hack_offset_check)));
theApp.SetConfig("UserHacks_AlphaHack", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hack_alpha_check))); theApp.SetConfig("UserHacks_AlphaHack", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hack_alpha_check)));
@ -519,7 +541,7 @@ override_GL_ARB_shading_language_420pack = -1
// NOT supported yet // NOT supported yet
theApp.SetConfig("msaa", 0); theApp.SetConfig("msaa", 0);
// Let's just be windowed for the moment. // Let's just be windowed for the moment.
theApp.SetConfig("windowed", 1); theApp.SetConfig("windowed", 1);

View File

@ -615,6 +615,10 @@ void GSRenderer::KeyEvent(GSKeyEventData* e)
m_fxaa = !m_fxaa; m_fxaa = !m_fxaa;
fprintf(stderr,"GSdx: fxaa is now %s.\n", m_fxaa ? "enabled" : "disabled"); fprintf(stderr,"GSdx: fxaa is now %s.\n", m_fxaa ? "enabled" : "disabled");
return; return;
case XK_Home:
m_shaderfx = !m_shaderfx;
printf("GSdx: External post-processing is now %s.\n", m_shaderfx ? "enabled" : "disabled");
return;
case XK_Shift_L: case XK_Shift_L:
case XK_Shift_R: case XK_Shift_R:
m_shift_key = true; m_shift_key = true;

View File

@ -170,7 +170,7 @@ bool GSShaderOGL::ValidateShader(GLuint s)
{ {
if (!m_debug_shader) return true; if (!m_debug_shader) return true;
GLint status; GLint status = 0;
gl_GetShaderiv(s, GL_COMPILE_STATUS, &status); gl_GetShaderiv(s, GL_COMPILE_STATUS, &status);
if (status) return true; if (status) return true;
@ -191,7 +191,7 @@ bool GSShaderOGL::ValidateProgram(GLuint p)
{ {
if (!m_debug_shader) return true; if (!m_debug_shader) return true;
GLint status; GLint status = 0;
gl_GetProgramiv(p, GL_LINK_STATUS, &status); gl_GetProgramiv(p, GL_LINK_STATUS, &status);
if (status) return true; if (status) return true;
@ -216,7 +216,7 @@ bool GSShaderOGL::ValidatePipeline(GLuint p)
// FIXME: might be mandatory to validate the pipeline // FIXME: might be mandatory to validate the pipeline
gl_ValidateProgramPipeline(p); gl_ValidateProgramPipeline(p);
GLint status; GLint status = 0;
gl_GetProgramPipelineiv(p, GL_VALIDATE_STATUS, &status); gl_GetProgramPipelineiv(p, GL_VALIDATE_STATUS, &status);
if (status) return true; if (status) return true;

View File

@ -1,4 +1,8 @@
#ifdef SHADER_MODEL #if defined(SHADER_MODEL) || defined(FXAA_GLSL_130)
#ifndef FXAA_GLSL_130
#define FXAA_GLSL_130 0
#endif
#define UHQ_FXAA 1 //High Quality Fast Approximate Anti Aliasing. Adapted for GSdx from Timothy Lottes FXAA 3.11. #define UHQ_FXAA 1 //High Quality Fast Approximate Anti Aliasing. Adapted for GSdx 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 FxaaSubpixMax 0.0 //[0.00 to 1.00] Amount of subpixel aliasing removal. 0.00: Edge only antialiasing (no blurring)
@ -7,6 +11,29 @@
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
[GLOBALS|FUNCTIONS] [GLOBALS|FUNCTIONS]
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
#if (FXAA_GLSL_130 == 1)
struct vertex_basic
{
vec4 p;
vec2 t;
};
#ifdef ENABLE_BINDLESS_TEX
layout(bindless_sampler, location = 0) uniform sampler2D TextureSampler;
#else
layout(binding = 0) uniform sampler2D TextureSampler;
#endif
in SHADER
{
vec4 p;
vec2 t;
} PSin;
layout(location = 0) out vec4 SV_Target0;
#else
#if (SHADER_MODEL >= 0x400) #if (SHADER_MODEL >= 0x400)
Texture2D Texture : register(t0); Texture2D Texture : register(t0);
@ -47,59 +74,7 @@ struct PS_OUTPUT
#endif #endif
}; };
float RGBLuminance(float3 color) #endif
{
const float3 lumCoeff = float3(0.2126729, 0.7151522, 0.0721750);
return dot(color.rgb, lumCoeff);
}
#define PixelSize float2(_rcpFrame.x, _rcpFrame.y)
/*------------------------------------------------------------------------------
[GAMMA PREPASS CODE SECTION]
------------------------------------------------------------------------------*/
float3 RGBGammaToLinear(float3 color, float gamma)
{
color = saturate(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 = saturate(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, float2 uv0)
{
#if (SHADER_MODEL >= 0x400)
color = Texture.Sample(TextureSampler, uv0);
#else
color = tex2D(TextureSampler, uv0);
#endif
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] [FXAA CODE SECTION]
@ -111,6 +86,8 @@ float4 PreGammaPass(float4 color, float2 uv0)
#elif (SHADER_MODEL >= 0x400) #elif (SHADER_MODEL >= 0x400)
#define FXAA_HLSL_4 1 #define FXAA_HLSL_4 1
#define FXAA_GATHER4_ALPHA 0 #define FXAA_GATHER4_ALPHA 0
#elif (FXAA_GLSL_130 == 1)
#define FXAA_GATHER4_ALPHA 1
#else #else
#define FXAA_HLSL_3 1 #define FXAA_HLSL_3 1
#define FXAA_GATHER4_ALPHA 0 #define FXAA_GATHER4_ALPHA 0
@ -138,6 +115,24 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; };
#define FxaaSat(x) saturate(x) #define FxaaSat(x) saturate(x)
#define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0)) #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
#define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0)) #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))
#elif (FXAA_GLSL_130 == 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)
#if (FXAA_GATHER4_ALPHA == 1)
// use #extension GL_ARB_gpu_shader5 : enable
#define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
#endif
#endif #endif
#define FxaaEdgeThreshold 0.063 #define FxaaEdgeThreshold 0.063
@ -156,6 +151,69 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; };
#define FXAA_QUALITY__P11 8.0 #define FXAA_QUALITY__P11 8.0
#define FXAA_QUALITY__P12 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);
}
#if (FXAA_GLSL_130 == 0)
#define PixelSize float2(_rcpFrame.x, _rcpFrame.y)
#endif
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, float2 uv0)
{
#if (SHADER_MODEL >= 0x400)
color = Texture.Sample(TextureSampler, uv0);
#elif (FXAA_GLSL_130 == 1)
color = texture(TextureSampler, uv0);
#else
color = tex2D(TextureSampler, uv0);
#endif
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) float FxaaLuma(float4 rgba)
{ {
rgba.w = RGBLuminance(rgba.xyz); rgba.w = RGBLuminance(rgba.xyz);
@ -463,7 +521,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
return float4(FxaaTexTop(tex, posM).xyz, lumaM); return float4(FxaaTexTop(tex, posM).xyz, lumaM);
} }
#if (FXAA_GLSL_130 == 1)
float4 FxaaPass(float4 FxaaColor, float2 uv0)
#else
float4 FxaaPass(float4 FxaaColor : COLOR0, float2 uv0 : TEXCOORD0) float4 FxaaPass(float4 FxaaColor : COLOR0, float2 uv0 : TEXCOORD0)
#endif
{ {
FxaaTex tex; FxaaTex tex;
@ -473,6 +535,13 @@ float4 FxaaPass(float4 FxaaColor : COLOR0, float2 uv0 : TEXCOORD0)
Texture.GetDimensions(PixelSize.x, PixelSize.y); Texture.GetDimensions(PixelSize.x, PixelSize.y);
FxaaColor = FxaaPixelShader(uv0, tex, 1.0/PixelSize.xy, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin); FxaaColor = FxaaPixelShader(uv0, tex, 1.0/PixelSize.xy, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin);
#elif (FXAA_GLSL_130 == 1)
tex = TextureSampler;
vec2 PixelSize = textureSize(tex, 0);
FxaaColor = FxaaPixelShader(uv0, tex, 1.0/PixelSize.xy, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin);
#else #else
tex = TextureSampler; tex = TextureSampler;
@ -485,6 +554,18 @@ float4 FxaaPass(float4 FxaaColor : COLOR0, float2 uv0 : TEXCOORD0)
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
[MAIN() & COMBINE PASS CODE SECTION] [MAIN() & COMBINE PASS CODE SECTION]
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
#if (FXAA_GLSL_130 == 1)
void ps_main()
{
vec4 color = texture(TextureSampler, PSin.t);
color = PreGammaPass(color, PSin.t);
color = FxaaPass(color, PSin.t);
SV_Target0 = color;
}
#else
PS_OUTPUT ps_main(VS_OUTPUT input) PS_OUTPUT ps_main(VS_OUTPUT input)
{ {
@ -506,4 +587,7 @@ PS_OUTPUT ps_main(VS_OUTPUT input)
return output; return output;
} }
#endif
#endif #endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff