mirror of
https://github.com/Tinob/Ishiiruka.git
synced 2024-06-16 03:17:27 -04:00
Implement post processing for Vulkan back end
This commit is contained in:
parent
8dc706d983
commit
b94fda8e1e
|
@ -1922,16 +1922,16 @@ float4 DitherPass(float4 color)
|
|||
[FXAA CODE SECTION]
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
#define FXAA_QUALITY__PS 9
|
||||
#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 4.0
|
||||
#define FXAA_QUALITY__P8 8.0
|
||||
#define FXAA_QUALITY_PS 9
|
||||
#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 4.0
|
||||
#define FXAA_QUALITY_P8 8.0
|
||||
|
||||
float FxaaLuma(float4 rgba) { return rgba.y; }
|
||||
|
||||
|
@ -2016,11 +2016,11 @@ float4 FxaaPixelShader(float2 RcpFrame, float Subpix, float EdgeThreshold, float
|
|||
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;
|
||||
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;
|
||||
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(SampleLocation(posN));
|
||||
float subpixE = subpixC * subpixC;
|
||||
|
@ -2036,11 +2036,11 @@ float4 FxaaPixelShader(float2 RcpFrame, float Subpix, float EdgeThreshold, float
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -2049,11 +2049,11 @@ float4 FxaaPixelShader(float2 RcpFrame, float Subpix, float EdgeThreshold, float
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -2062,11 +2062,11 @@ float4 FxaaPixelShader(float2 RcpFrame, float Subpix, float EdgeThreshold, float
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -2075,11 +2075,11 @@ float4 FxaaPixelShader(float2 RcpFrame, float Subpix, float EdgeThreshold, float
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -2088,11 +2088,11 @@ float4 FxaaPixelShader(float2 RcpFrame, float Subpix, float EdgeThreshold, float
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -2101,11 +2101,11 @@ float4 FxaaPixelShader(float2 RcpFrame, float Subpix, float EdgeThreshold, float
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -2114,11 +2114,11 @@ float4 FxaaPixelShader(float2 RcpFrame, float Subpix, float EdgeThreshold, float
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -2127,11 +2127,11 @@ float4 FxaaPixelShader(float2 RcpFrame, float Subpix, float EdgeThreshold, float
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2329,12 +2329,7 @@ float4 BorderPass(float4 colorInput, float2 tex)
|
|||
float2 border = (GetInvResolution().xy * GetOption(BorderWidth));
|
||||
float2 within_border = saturate((-tex * tex + tex) - (-border * border + border));
|
||||
|
||||
#if API_OPENGL == 1
|
||||
bvec2 cond = notEqual(within_border, vec2(0.0f, 0.0f));
|
||||
colorInput.rgb = all(cond) ? colorInput.rgb : border_color_float;
|
||||
#else
|
||||
colorInput.rgb = all(within_border) ? colorInput.rgb : border_color_float;
|
||||
#endif
|
||||
|
||||
return colorInput;
|
||||
|
||||
|
|
|
@ -1067,7 +1067,7 @@ float4 SSAO()
|
|||
float fSampleDepth = SampleDepthLocation(location);
|
||||
float fDepthDelta = saturate(sD - fSampleDepth);
|
||||
|
||||
fDepthDelta *= 1 - smoothstep(0, GetOption(E_MAX_DEPTH), fDepthDelta);
|
||||
fDepthDelta *= 1.0f - smoothstep(0.0f, GetOption(E_MAX_DEPTH), fDepthDelta);
|
||||
|
||||
if (fDepthDelta > GetOption(F_MIN_DEPTH) && fDepthDelta < GetOption(E_MAX_DEPTH))
|
||||
{
|
||||
|
@ -1160,8 +1160,8 @@ float4 PS_AO_SSGI()
|
|||
float ii_curr_sample_radius = sample_radius[i] * GetOption(fSSGISamplingRange) * 30;
|
||||
float ao_curr_sample_radius = sample_radius[i] * GetOption(fSSGISamplingRange) * 5;
|
||||
|
||||
gi.a += clamp(0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth, 2 * ao_curr_sample_radius);
|
||||
gi.a -= clamp(0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth - GetOption(fSSGIModelThickness), 2 * ao_curr_sample_radius);
|
||||
gi.a += clamp(0.0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth, 2 * ao_curr_sample_radius);
|
||||
gi.a -= clamp(0.0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth - GetOption(fSSGIModelThickness), 2 * ao_curr_sample_radius);
|
||||
|
||||
if ((sample_depth < ii_sample_center_depth + ii_curr_sample_radius) &&
|
||||
(sample_depth > ii_sample_center_depth - ii_curr_sample_radius)) {
|
||||
|
@ -1579,16 +1579,16 @@ float4 TexSharpenPass(float4 color)
|
|||
[FXAA CODE SECTION]
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
#define FXAA_QUALITY__PS 9
|
||||
#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 4.0
|
||||
#define FXAA_QUALITY__P8 8.0
|
||||
#define FXAA_QUALITY_PS 9
|
||||
#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 4.0
|
||||
#define FXAA_QUALITY_P8 8.0
|
||||
|
||||
float FxaaLuma(float4 rgba) { return rgba.y; }
|
||||
|
||||
|
@ -1672,11 +1672,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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;
|
||||
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(SampleLocation(posN));
|
||||
float subpixE = subpixC * subpixC;
|
||||
|
@ -1692,11 +1692,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1705,11 +1705,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1718,11 +1718,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1731,11 +1731,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1744,11 +1744,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1757,11 +1757,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1770,11 +1770,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1783,11 +1783,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1919,7 +1919,7 @@ void A_ReduceSize()
|
|||
float4 reducendcolor = float4(pow(rawcolor.rgb, power), 1.0);
|
||||
if (OptionEnabled(C_GAUSSIAN_ANAMFLARE))
|
||||
{
|
||||
reducendcolor.w = max(0, dot(reducendcolor.xyz, float3(0.333, 0.333, 0.333)) - GetOption(A_ANAMFLARE_THRESHOLD));
|
||||
reducendcolor.w = max(0.0, dot(reducendcolor.xyz, float3(0.333, 0.333, 0.333)) - GetOption(A_ANAMFLARE_THRESHOLD));
|
||||
}
|
||||
SetOutput(reducendcolor);
|
||||
}
|
||||
|
|
|
@ -1065,7 +1065,7 @@ float4 SSAO()
|
|||
float fSampleDepth = SampleDepthLocation(location);
|
||||
float fDepthDelta = saturate(sD - fSampleDepth);
|
||||
|
||||
fDepthDelta *= 1 - smoothstep(0, GetOption(E_MAX_DEPTH), fDepthDelta);
|
||||
fDepthDelta *= 1.0f - smoothstep(0.0f, GetOption(E_MAX_DEPTH), fDepthDelta);
|
||||
|
||||
if (fDepthDelta > GetOption(F_MIN_DEPTH) && fDepthDelta < GetOption(E_MAX_DEPTH))
|
||||
{
|
||||
|
@ -1158,8 +1158,8 @@ float4 PS_AO_SSGI()
|
|||
float ii_curr_sample_radius = sample_radius[i] * GetOption(fSSGISamplingRange) * 30;
|
||||
float ao_curr_sample_radius = sample_radius[i] * GetOption(fSSGISamplingRange) * 5;
|
||||
|
||||
gi.a += clamp(0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth, 2 * ao_curr_sample_radius);
|
||||
gi.a -= clamp(0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth - GetOption(fSSGIModelThickness), 2 * ao_curr_sample_radius);
|
||||
gi.a += clamp(0.0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth, 2 * ao_curr_sample_radius);
|
||||
gi.a -= clamp(0.0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth - GetOption(fSSGIModelThickness), 2 * ao_curr_sample_radius);
|
||||
|
||||
if ((sample_depth < ii_sample_center_depth + ii_curr_sample_radius) &&
|
||||
(sample_depth > ii_sample_center_depth - ii_curr_sample_radius)) {
|
||||
|
@ -1577,16 +1577,16 @@ float4 TexSharpenPass(float4 color)
|
|||
[FXAA CODE SECTION]
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
#define FXAA_QUALITY__PS 9
|
||||
#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 4.0
|
||||
#define FXAA_QUALITY__P8 8.0
|
||||
#define FXAA_QUALITY_PS 9
|
||||
#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 4.0
|
||||
#define FXAA_QUALITY_P8 8.0
|
||||
|
||||
float FxaaLuma(float4 rgba) { return rgba.y; }
|
||||
|
||||
|
@ -1670,11 +1670,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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;
|
||||
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(SampleLocation(posN));
|
||||
float subpixE = subpixC * subpixC;
|
||||
|
@ -1690,11 +1690,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1703,11 +1703,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1716,11 +1716,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1729,11 +1729,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1742,11 +1742,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1755,11 +1755,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1768,11 +1768,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;
|
||||
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(SampleLocation(posN.xy));
|
||||
|
@ -1781,11 +1781,11 @@ float4 FxaaPixelShader(float4 rgbyM, float2 RcpFrame, float Subpix, float EdgeTh
|
|||
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;
|
||||
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 (!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1917,7 +1917,7 @@ void A_ReduceSize()
|
|||
float4 reducendcolor = float4(pow(rawcolor.rgb, power), 1.0);
|
||||
if (OptionEnabled(C_GAUSSIAN_ANAMFLARE))
|
||||
{
|
||||
reducendcolor.w = max(0, dot(reducendcolor.xyz, float3(0.333, 0.333, 0.333)) - GetOption(A_ANAMFLARE_THRESHOLD));
|
||||
reducendcolor.w = max(0.0, dot(reducendcolor.xyz, float3(0.333, 0.333, 0.333)) - GetOption(A_ANAMFLARE_THRESHOLD));
|
||||
}
|
||||
SetOutput(reducendcolor);
|
||||
}
|
||||
|
|
|
@ -351,7 +351,7 @@ void SSAO()
|
|||
float fSampleDepth = SampleDepthLocation(location);
|
||||
float fDepthDelta = saturate(sD - fSampleDepth);
|
||||
|
||||
fDepthDelta *= 1-smoothstep(0,GetOption(E_MAX_DEPTH),fDepthDelta);
|
||||
fDepthDelta *= 1.0-smoothstep(0.0,GetOption(E_MAX_DEPTH),fDepthDelta);
|
||||
|
||||
if (fDepthDelta > GetOption(F_MIN_DEPTH) && fDepthDelta < GetOption(E_MAX_DEPTH))
|
||||
{
|
||||
|
|
|
@ -202,8 +202,8 @@ void PS_AO_SSGI()
|
|||
float ii_curr_sample_radius = sample_radius[i] * GetOption(fSSGISamplingRange) * 20;
|
||||
float ao_curr_sample_radius = sample_radius[i] * GetOption(fSSGISamplingRange) * 5;
|
||||
|
||||
gi.a += clamp(0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth, 2 * ao_curr_sample_radius);
|
||||
gi.a -= clamp(0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth - GetOption(fSSGIModelThickness), 2 * ao_curr_sample_radius);
|
||||
gi.a += clamp(0.0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth, 2 * ao_curr_sample_radius);
|
||||
gi.a -= clamp(0.0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth - GetOption(fSSGIModelThickness), 2.0 * ao_curr_sample_radius);
|
||||
|
||||
if ((sample_depth < ii_sample_center_depth + ii_curr_sample_radius) &&
|
||||
(sample_depth > ii_sample_center_depth - ii_curr_sample_radius)) {
|
||||
|
|
|
@ -53,7 +53,7 @@ std::array<SHADERUID, PIXEL_SHADER_RENDER_MODE::PSRM_DEPTH_ONLY + 1> ProgramShad
|
|||
ProgramShaderCache::PCacheEntry* ProgramShaderCache::last_uber_entry;
|
||||
UBERSHADERUID ProgramShaderCache::last_uber_uid;
|
||||
|
||||
static char s_glsl_header[2048] = "";
|
||||
static char s_glsl_header[4096] = "";
|
||||
|
||||
static std::string GetGLSLVersionString()
|
||||
{
|
||||
|
@ -968,7 +968,19 @@ void ProgramShaderCache::CreateHeader()
|
|||
"#define ddy dFdy\n"
|
||||
"#define rsqrt inversesqrt\n"
|
||||
|
||||
"bool all(float2 val) { return (val.x != 0.0) && (val.y != 0.0); }\n"
|
||||
"bool all(float3 val) { return (val.x != 0.0) && (val.y != 0.0) && (val.z != 0.0); }\n"
|
||||
"bool all(float4 val) { return (val.x != 0.0) && (val.y != 0.0) && (val.z != 0.0) && (val.w != 0.0); }\n"
|
||||
"bool all(int2 val) { return (val.x != 0) && (val.y != 0); }\n"
|
||||
"bool all(int3 val) { return (val.x != 0) && (val.y != 0) && (val.z != 0); }\n"
|
||||
"bool all(int4 val) { return (val.x != 0) && (val.y != 0) && (val.z != 0) && (val.w != 0); }\n"
|
||||
|
||||
"bool any(float2 val) { return (val.x != 0.0) || (val.y != 0.0); }\n"
|
||||
"bool any(float3 val) { return (val.x != 0.0) || (val.y != 0.0) || (val.z != 0.0); }\n"
|
||||
"bool any(float4 val) { return (val.x != 0.0) || (val.y != 0.0) || (val.z != 0.0) || (val.w != 0.0); }\n"
|
||||
"bool any(int2 val) { return (val.x != 0) || (val.y != 0); }\n"
|
||||
"bool any(int3 val) { return (val.x != 0) || (val.y != 0) || (val.z != 0); }\n"
|
||||
"bool any(int4 val) { return (val.x != 0) || (val.y != 0) || (val.z != 0) || (val.w != 0); }\n"
|
||||
|
||||
, GetGLSLVersionString().c_str()
|
||||
, v < GLSL_140 ? "#extension GL_ARB_uniform_buffer_object : enable" : ""
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include "VideoBackends/Vulkan/CommandBufferManager.h"
|
||||
#include "VideoBackends/Vulkan/ObjectCache.h"
|
||||
#include "VideoBackends/Vulkan/PostProcessing.h"
|
||||
#include "VideoBackends/Vulkan/Renderer.h"
|
||||
#include "VideoBackends/Vulkan/StagingTexture2D.h"
|
||||
#include "VideoBackends/Vulkan/StateTracker.h"
|
||||
#include "VideoBackends/Vulkan/StreamBuffer.h"
|
||||
|
@ -1460,19 +1462,52 @@ void XFBSource::CopyEFB(float gamma)
|
|||
// Pending/batched EFB pokes should be included in the copied image.
|
||||
FramebufferManager::GetInstance()->FlushEFBPokes();
|
||||
|
||||
bool apply_post_proccesing = g_renderer->GetPostProcessor()->ShouldTriggerOnSwap();
|
||||
bool depth_copy_required = g_renderer->GetPostProcessor()->XFBDepthDataRequired();
|
||||
if (depth_copy_required && !m_depth_texture)
|
||||
{
|
||||
TextureConfig config = m_texture->GetConfig();
|
||||
config.pcformat = HostTextureFormat::PC_TEX_FMT_R_FLOAT;
|
||||
m_depth_texture = g_texture_cache->AllocateTexture(config);
|
||||
}
|
||||
if (apply_post_proccesing)
|
||||
{
|
||||
g_renderer->GetPostProcessor()->PostProcessEFBToTexture(m_texture->GetInternalObject());
|
||||
}
|
||||
g_renderer->GetPostProcessor()->OnEndFrame();
|
||||
if (apply_post_proccesing && !depth_copy_required)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Virtual XFB, copy EFB at native resolution to m_texture
|
||||
MathUtil::Rectangle<int> rect(0, 0, static_cast<int>(texWidth), static_cast<int>(texHeight));
|
||||
VkRect2D vk_rect = { { rect.left, rect.top },
|
||||
{ static_cast<u32>(rect.GetWidth()), static_cast<u32>(rect.GetHeight()) } };
|
||||
|
||||
Texture2D* src_texture = FramebufferManager::GetInstance()->ResolveEFBColorTexture(vk_rect);
|
||||
static_cast<VKTexture*>(m_texture.get())->CopyRectangleFromTexture(src_texture, rect, rect);
|
||||
|
||||
// If we sourced directly from the EFB framebuffer, restore it to a color attachment.
|
||||
if (src_texture == FramebufferManager::GetInstance()->GetEFBColorTexture())
|
||||
if (!apply_post_proccesing)
|
||||
{
|
||||
src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
Texture2D* src_texture = FramebufferManager::GetInstance()->ResolveEFBColorTexture(vk_rect);
|
||||
static_cast<VKTexture*>(m_texture.get())->CopyRectangleFromTexture(src_texture, rect, rect);
|
||||
|
||||
// If we sourced directly from the EFB framebuffer, restore it to a color attachment.
|
||||
if (src_texture == FramebufferManager::GetInstance()->GetEFBColorTexture())
|
||||
{
|
||||
src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
}
|
||||
if (depth_copy_required)
|
||||
{
|
||||
Texture2D* src_texture = FramebufferManager::GetInstance()->ResolveEFBDepthTexture(vk_rect);
|
||||
static_cast<VKTexture*>(m_depth_texture.get())->CopyRectangleFromTexture(src_texture, rect, rect);
|
||||
|
||||
// If we sourced directly from the EFB framebuffer, restore it to a color attachment.
|
||||
if (src_texture == FramebufferManager::GetInstance()->GetEFBDepthTexture())
|
||||
{
|
||||
src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "VideoBackends/Vulkan/Renderer.h"
|
||||
#include "VideoBackends/Vulkan/StateTracker.h"
|
||||
#include "VideoBackends/Vulkan/ShaderCompiler.h"
|
||||
#include "VideoBackends/Vulkan/SwapChain.h"
|
||||
#include "VideoBackends/Vulkan/Texture2D.h"
|
||||
#include "VideoBackends/Vulkan/VulkanContext.h"
|
||||
|
||||
|
@ -29,41 +30,45 @@ namespace Vulkan
|
|||
{
|
||||
|
||||
static const char* s_vertex_shader = R"(
|
||||
out vec2 v_source_uv;
|
||||
out vec2 v_target_uv;
|
||||
flat out float v_layer;
|
||||
layout(location = 0) in vec4 ipos;
|
||||
layout(location = 5) in vec4 icol0;
|
||||
layout(location = 8) in vec3 itex0;
|
||||
layout(location = 0) out vec2 v_source_uv;
|
||||
layout(location = 1) out vec2 v_target_uv;
|
||||
layout(location = 2) flat out float v_layer;
|
||||
void main(void)
|
||||
{
|
||||
vec2 rawpos = vec2(gl_VertexID&1, gl_VertexID&2);
|
||||
gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);
|
||||
v_source_uv = rawpos * u_source_rect.zw + u_source_rect.xy;
|
||||
v_target_uv = rawpos;
|
||||
gl_Position = ipos;
|
||||
v_source_uv = itex0.xy;
|
||||
v_target_uv = ipos.xy;
|
||||
v_layer = u_src_layer;
|
||||
}
|
||||
)";
|
||||
|
||||
static const char* s_layered_vertex_shader = R"(
|
||||
out vec2 i_source_uv;
|
||||
out vec2 i_target_uv;
|
||||
layout(location = 0) in vec4 ipos;
|
||||
layout(location = 5) in vec4 icol0;
|
||||
layout(location = 8) in vec3 itex0;
|
||||
layout(location = 0) out vec2 v_source_uv;
|
||||
layout(location = 1) out vec2 v_target_uv;
|
||||
void main(void)
|
||||
{
|
||||
vec2 rawpos = vec2(gl_VertexID&1, gl_VertexID&2);
|
||||
gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);
|
||||
i_source_uv = rawpos * u_source_rect.zw + u_source_rect.xy;
|
||||
i_target_uv = rawpos;
|
||||
gl_Position = ipos;
|
||||
v_source_uv = itex0.xy;
|
||||
v_target_uv = ipos.xy;
|
||||
}
|
||||
)";
|
||||
|
||||
static const char* s_geometry_shader = R"(
|
||||
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices = %d) out;
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices = %d) out;
|
||||
|
||||
in vec2 i_source_uv[3];
|
||||
in vec2 i_target_uv[3];
|
||||
out vec2 v_source_uv;
|
||||
out vec2 v_target_uv;
|
||||
flat out float v_layer;
|
||||
layout(location = 0) in vec2 i_source_uv[3];
|
||||
layout(location = 1) in vec2 i_target_uv[3];
|
||||
layout(location = 0) out vec2 v_source_uv;
|
||||
layout(location = 1) out vec2 v_target_uv;
|
||||
flat out float v_layer;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -191,7 +196,7 @@ void VulkanPostProcessingShader::Draw(PostProcessor* p,
|
|||
TargetSize output_size;
|
||||
|
||||
u32 shader_buffer_size;
|
||||
void* shader_buffer_data = m_config->UpdateConfigurationBuffer(&shader_buffer_size, true);
|
||||
void* shader_buffer_data = m_config->UpdateConfigurationBuffer(&shader_buffer_size);
|
||||
if (!shader_buffer_data)
|
||||
{
|
||||
shader_buffer_data = m_config->GetConfigurationBuffer(&shader_buffer_size);
|
||||
|
@ -224,7 +229,7 @@ void VulkanPostProcessingShader::Draw(PostProcessor* p,
|
|||
}
|
||||
if (dst->GetFrameBuffer() == nullptr)
|
||||
{
|
||||
dst->AddFramebuffer(TextureCache::GetInstance()->GetRenderPass());
|
||||
dst->AddFramebuffer(TextureCache::GetInstance()->GetRenderPass(dst->GetFormat()));
|
||||
}
|
||||
dst->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
@ -235,10 +240,9 @@ void VulkanPostProcessingShader::Draw(PostProcessor* p,
|
|||
geometry_shader,
|
||||
reinterpret_cast<RenderPassVulkanData*>(pass.shader)->m_fragment_shader);
|
||||
VkRect2D region = {
|
||||
{ dst_rect.left, dst_rect.top },
|
||||
{ static_cast<u32>(dst_rect.GetWidth()), static_cast<u32>(dst_rect.GetHeight()) } };
|
||||
{ output_rect.left, output_rect.top },
|
||||
{ static_cast<u32>(output_rect.GetWidth()), static_cast<u32>(output_rect.GetHeight()) } };
|
||||
VkClearValue clear_value = { { { 0.0f, 0.0f, 0.0f, 1.0f } } };
|
||||
draw.BeginRenderPass(dst->GetFrameBuffer(), region, &clear_value);
|
||||
if (shader_buffer_size && shader_buffer_data)
|
||||
{
|
||||
void* psuniforms = draw.AllocatePSUniforms(shader_buffer_size);
|
||||
|
@ -281,7 +285,7 @@ void VulkanPostProcessingShader::Draw(PostProcessor* p,
|
|||
}
|
||||
break;
|
||||
default:
|
||||
HostTexture* i_texture = input.texture ? input.texture.get() : input.prev_texture;
|
||||
HostTexture * i_texture = input.texture ? input.texture.get() : input.prev_texture;
|
||||
if (i_texture != nullptr)
|
||||
{
|
||||
input_texture = reinterpret_cast<Texture2D*>(i_texture->GetInternalObject());
|
||||
|
@ -299,7 +303,7 @@ void VulkanPostProcessingShader::Draw(PostProcessor* p,
|
|||
input_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
}
|
||||
draw.SetPSSampler(i, src_texture->GetView(), parent->GetSamplerHandle(input.texture_sampler - 1));
|
||||
draw.SetPSSampler(i, input_texture->GetView(), parent->GetSamplerHandle(input.texture_sampler - 1));
|
||||
}
|
||||
parent->MapAndUpdateUniformBuffer(input_sizes, output_rect, output_size, src_rect, src_size, src_layer, gamma);
|
||||
void* vsuniforms = draw.AllocateVSUniforms(POST_PROCESSING_CONTANTS_BUFFER_SIZE);
|
||||
|
@ -308,8 +312,8 @@ void VulkanPostProcessingShader::Draw(PostProcessor* p,
|
|||
parent->GetConstatsData(),
|
||||
POST_PROCESSING_CONTANTS_BUFFER_SIZE);
|
||||
draw.CommitVSUniforms(POST_PROCESSING_CONTANTS_BUFFER_SIZE);
|
||||
draw.SetPSSampler(0, src_texture->GetView(), g_object_cache->GetLinearSampler());
|
||||
draw.DrawQuad(dst_rect.left, dst_rect.top, dst_rect.GetWidth(), dst_rect.GetHeight(),
|
||||
draw.BeginRenderPass(dst->GetFrameBuffer(), region, &clear_value);
|
||||
draw.DrawQuad(output_rect.left, output_rect.top, output_rect.GetWidth(), output_rect.GetHeight(),
|
||||
src_rect.left, src_rect.top, 0, src_rect.GetWidth(), src_rect.GetHeight(),
|
||||
static_cast<int>(src_texture->GetWidth()),
|
||||
static_cast<int>(src_texture->GetHeight()));
|
||||
|
@ -432,17 +436,17 @@ bool VulkanPostProcessor::CreateCommonShaders()
|
|||
PostProcessor::GetUniformBufferShaderSource(API_VULKAN, nullptr, shader, false);
|
||||
shader += s_vertex_shader;
|
||||
m_vertex_shader = Util::CompileAndCreateVertexShader(shader);
|
||||
result = result && m_vertex_shader != VK_NULL_HANDLE;
|
||||
result = result && m_vertex_shader != VK_NULL_HANDLE;
|
||||
shader.clear();
|
||||
PostProcessor::GetUniformBufferShaderSource(API_VULKAN, nullptr, shader, false);
|
||||
shader += s_layered_vertex_shader;
|
||||
m_layered_vertex_shader = Util::CompileAndCreateVertexShader(shader);
|
||||
result = result && m_layered_vertex_shader != VK_NULL_HANDLE;
|
||||
result = result && m_layered_vertex_shader != VK_NULL_HANDLE;
|
||||
shader.clear();
|
||||
PostProcessor::GetUniformBufferShaderSource(API_VULKAN, nullptr, shader, false);
|
||||
shader += StringFromFormat(s_geometry_shader, 6, 2);
|
||||
m_layered_geometry_shader = Util::CompileAndCreateGeometryShader(shader);
|
||||
result = result && m_layered_geometry_shader != VK_NULL_HANDLE;
|
||||
result = result && m_layered_geometry_shader != VK_NULL_HANDLE;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -458,17 +462,22 @@ std::unique_ptr<PostProcessingShader> VulkanPostProcessor::CreateShader(PostProc
|
|||
|
||||
void VulkanPostProcessor::PostProcessEFBToTexture(uintptr_t dst_texture)
|
||||
{
|
||||
// Can't do this within a game render pass.
|
||||
StateTracker::GetInstance()->EndRenderPass();
|
||||
StateTracker::GetInstance()->SetPendingRebind();
|
||||
// Apply normal post-process process, but to the EFB buffers.
|
||||
// Uses the current viewport as the "visible" region to post-process.
|
||||
TargetRectangle target_rect = { 0, 0, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight() };
|
||||
TargetSize target_size(g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight());
|
||||
|
||||
VkRect2D region = {
|
||||
{ target_rect.left, target_rect.top },
|
||||
{ static_cast<u32>(target_rect.GetWidth()), static_cast<u32>(target_rect.GetHeight()) } };
|
||||
// Source and target textures, if MSAA is enabled, this needs to be resolved
|
||||
Texture2D* color_texture = FramebufferManager::GetInstance()->GetResolvedEFBColorTexture();
|
||||
Texture2D* color_texture = FramebufferManager::GetInstance()->ResolveEFBColorTexture(region);
|
||||
Texture2D* depth_texture = nullptr;
|
||||
if (m_requires_depth_buffer)
|
||||
{
|
||||
depth_texture = FramebufferManager::GetInstance()->GetEFBDepthTexture();
|
||||
depth_texture = FramebufferManager::GetInstance()->ResolveEFBDepthTexture(region);
|
||||
}
|
||||
// Invoke post process process
|
||||
PostProcess(nullptr, nullptr, nullptr,
|
||||
|
@ -480,6 +489,9 @@ void VulkanPostProcessor::PostProcessEFBToTexture(uintptr_t dst_texture)
|
|||
|
||||
void VulkanPostProcessor::PostProcessEFB(const TargetRectangle& src_rect, const TargetSize& src_size)
|
||||
{
|
||||
// Can't do this within a game render pass.
|
||||
StateTracker::GetInstance()->EndRenderPass();
|
||||
StateTracker::GetInstance()->SetPendingRebind();
|
||||
// Apply normal post-process process, but to the EFB buffers.
|
||||
// Uses the current viewport as the "visible" region to post-process.
|
||||
// In Vulkan, the viewport rectangle must fit within the render target.
|
||||
|
@ -489,13 +501,15 @@ void VulkanPostProcessor::PostProcessEFB(const TargetRectangle& src_rect, const
|
|||
target_rect.top = src_rect.top >= 0 ? src_rect.top : 0;
|
||||
target_rect.right = src_rect.right <= src_size.width ? src_rect.right : src_size.width;
|
||||
target_rect.bottom = src_rect.bottom <= src_size.height ? src_rect.bottom : src_size.height;
|
||||
|
||||
VkRect2D region = {
|
||||
{ target_rect.left, target_rect.top },
|
||||
{ static_cast<u32>(target_rect.GetWidth()), static_cast<u32>(target_rect.GetHeight()) } };
|
||||
// Source and target textures, if MSAA is enabled, this needs to be resolved
|
||||
Texture2D* color_texture = FramebufferManager::GetInstance()->GetResolvedEFBColorTexture();
|
||||
Texture2D* color_texture = FramebufferManager::GetInstance()->ResolveEFBColorTexture(region);
|
||||
Texture2D* depth_texture = nullptr;
|
||||
if (m_requires_depth_buffer)
|
||||
{
|
||||
depth_texture = FramebufferManager::GetInstance()->GetEFBDepthTexture();
|
||||
depth_texture = FramebufferManager::GetInstance()->ResolveEFBDepthTexture(region);
|
||||
}
|
||||
|
||||
// Invoke post process process
|
||||
|
@ -567,7 +581,7 @@ void VulkanPostProcessor::CopyTexture(const TargetRectangle& dst_rect, uintptr_t
|
|||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
if (dst_texture->GetFrameBuffer() == nullptr)
|
||||
{
|
||||
dst_texture->AddFramebuffer(TextureCache::GetInstance()->GetRenderPass());
|
||||
dst_texture->AddFramebuffer(TextureCache::GetInstance()->GetRenderPass(dst_texture->GetFormat()));
|
||||
}
|
||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD), dst_texture->GetDefaultRenderPass(),
|
||||
|
@ -575,8 +589,8 @@ void VulkanPostProcessor::CopyTexture(const TargetRectangle& dst_rect, uintptr_t
|
|||
g_shader_cache->GetPassthroughGeometryShader(), TextureCache::GetInstance()->GetCopyShader());
|
||||
|
||||
VkRect2D region = {
|
||||
{ dst_rect.left, dst_rect.top },
|
||||
{ static_cast<u32>(dst_rect.GetWidth()), static_cast<u32>(dst_rect.GetHeight()) } };
|
||||
{ 0, 0 },
|
||||
{ static_cast<u32>(dst_texture->GetWidth()), static_cast<u32>(dst_texture->GetHeight()) } };
|
||||
VkClearValue clear_value = { { { 0.0f, 0.0f, 0.0f, 1.0f } } };
|
||||
draw.BeginRenderPass(dst_texture->GetFrameBuffer(), region, &clear_value);
|
||||
draw.SetPSSampler(0, src_texture->GetView(), g_object_cache->GetLinearSampler());
|
||||
|
|
|
@ -128,7 +128,6 @@ bool Renderer::Initialize()
|
|||
// Ensure all pipelines previously used by the game have been created.
|
||||
StateTracker::GetInstance()->ReloadPipelineUIDCache();
|
||||
StateTracker::GetInstance()->ReloadUberPipelineUIDCache();
|
||||
/*
|
||||
// Initialize post processing.
|
||||
m_post_processor = std::make_unique<VulkanPostProcessor>();
|
||||
if (!m_post_processor->Initialize())
|
||||
|
@ -136,7 +135,6 @@ bool Renderer::Initialize()
|
|||
PanicAlert("failed to initialize post processor.");
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
// Various initialization routines will have executed commands on the command buffer.
|
||||
// Execute what we have done before beginning the first frame.
|
||||
g_command_buffer_mgr->PrepareToSubmitCommandBuffer();
|
||||
|
@ -189,7 +187,7 @@ void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
|
|||
u32 backbuffer_width = m_swap_chain->GetWidth();
|
||||
u32 backbuffer_height = m_swap_chain->GetHeight();
|
||||
|
||||
m_raster_font->PrintMultiLineText(m_swap_chain->GetRenderPass(), text,
|
||||
m_raster_font->PrintMultiLineText(m_swap_chain->GetRenderAppendPass(), text,
|
||||
left * 2.0f / static_cast<float>(backbuffer_width) - 1,
|
||||
1 - top * 2.0f / static_cast<float>(backbuffer_height),
|
||||
backbuffer_width, backbuffer_height, color);
|
||||
|
@ -521,7 +519,8 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height
|
|||
Core::Callback_VideoCopiedToXFB(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_ActiveConfig.bUseXFB)
|
||||
m_post_processor->OnEndFrame();
|
||||
// End the current render pass.
|
||||
StateTracker::GetInstance()->EndRenderPass();
|
||||
StateTracker::GetInstance()->OnEndFrame();
|
||||
|
@ -672,19 +671,22 @@ void Renderer::DrawEFB(VkRenderPass render_pass, const TargetRectangle& t_rc, co
|
|||
if (g_ActiveConfig.iMultisamples > 1)
|
||||
{
|
||||
efb_color_texture = FramebufferManager::GetInstance()->GetResolvedEFBColorTexture();
|
||||
if (m_post_processor && m_post_processor->RequiresDepthBuffer())
|
||||
{
|
||||
efb_depth_texture = FramebufferManager::GetInstance()->GetResolvedEFBDepthTexture();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
efb_color_texture = FramebufferManager::GetInstance()->GetEFBColorTexture();
|
||||
if (m_post_processor && m_post_processor->RequiresDepthBuffer())
|
||||
{
|
||||
efb_depth_texture = FramebufferManager::GetInstance()->GetEFBDepthTexture();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_post_processor && m_post_processor->RequiresDepthBuffer())
|
||||
{
|
||||
VkRect2D region = {
|
||||
{ t_rc.left, t_rc.top },
|
||||
{ static_cast<u32>(t_rc.GetWidth()), static_cast<u32>(t_rc.GetHeight()) } };
|
||||
region = Util::ClampRect2D(region, FramebufferManager::GetInstance()->GetEFBWidth(),
|
||||
FramebufferManager::GetInstance()->GetEFBHeight());
|
||||
efb_depth_texture = FramebufferManager::GetInstance()->ResolveEFBDepthTexture(region);
|
||||
}
|
||||
|
||||
TargetRectangle scaled_source_rc(scaled_src_rc);
|
||||
TargetSize tex_size(efb_color_texture->GetWidth(), efb_color_texture->GetHeight());
|
||||
// Post processing active?
|
||||
|
@ -798,28 +800,27 @@ void Renderer::DrawScreen(const TargetRectangle& scaled_efb_rect, u32 xfb_addr,
|
|||
// a render pass, unless the render pass declares a self-dependency.
|
||||
Texture2D* backbuffer = m_swap_chain->GetCurrentTexture();
|
||||
backbuffer->OverrideImageLayout(VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
|
||||
const TargetSize dst_size = { static_cast<int>(backbuffer->GetWidth()), static_cast<int>(backbuffer->GetHeight()) };
|
||||
// Draw guest buffers (EFB or XFB)
|
||||
DrawFrame(m_swap_chain->GetRenderClearPass(), GetTargetRectangle(), scaled_efb_rect, xfb_addr,
|
||||
xfb_sources, xfb_count, backbuffer, dst_size, fb_width, fb_stride, fb_height, gamma);
|
||||
|
||||
backbuffer->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Begin render pass for rendering to the swap chain.
|
||||
VkClearValue clear_value = { { { 0.0f, 0.0f, 0.0f, 1.0f } } };
|
||||
// Begin render pass for rendering to the swap chain.
|
||||
VkRenderPassBeginInfo info = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
nullptr,
|
||||
m_swap_chain->GetRenderPass(),
|
||||
m_swap_chain->GetCurrentFramebuffer(),
|
||||
{ { 0, 0 },{ backbuffer->GetWidth(), backbuffer->GetHeight() } },
|
||||
1,
|
||||
&clear_value };
|
||||
nullptr,
|
||||
m_swap_chain->GetRenderAppendPass(),
|
||||
m_swap_chain->GetCurrentFramebuffer(),
|
||||
{ { 0, 0 },{ backbuffer->GetWidth(), backbuffer->GetHeight() } },
|
||||
0,
|
||||
nullptr };
|
||||
vkCmdBeginRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer(), &info,
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
const TargetSize dst_size = { static_cast<int>(backbuffer->GetWidth()), static_cast<int>(backbuffer->GetHeight()) };
|
||||
// Draw guest buffers (EFB or XFB)
|
||||
DrawFrame(m_swap_chain->GetRenderPass(), GetTargetRectangle(), scaled_efb_rect, xfb_addr,
|
||||
xfb_sources, xfb_count, backbuffer, dst_size, fb_width, fb_stride, fb_height, gamma);
|
||||
|
||||
// Draw OSD
|
||||
Util::SetViewportAndScissor(g_command_buffer_mgr->GetCurrentCommandBuffer(), 0, 0,
|
||||
backbuffer->GetWidth(), backbuffer->GetHeight());
|
||||
DrawDebugText();
|
||||
OSD::DoCallbacks(OSD::CallbackType::OnFrame);
|
||||
OSD::DrawMessages();
|
||||
|
@ -862,10 +863,11 @@ bool Renderer::DrawFrameDump(const TargetRectangle& scaled_efb_rect, u32 xfb_add
|
|||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
vkCmdClearAttachments(g_command_buffer_mgr->GetCurrentCommandBuffer(), 1, &clear_attachment, 1,
|
||||
&clear_rect);
|
||||
vkCmdEndRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer());
|
||||
const TargetSize dst_size = { static_cast<int>(width), static_cast<int>(height) };
|
||||
DrawFrame(m_frame_dump_render_texture->GetDefaultRenderPass(), target_rect,
|
||||
scaled_efb_rect, xfb_addr, xfb_sources, xfb_count, m_frame_dump_render_texture.get(), dst_size, fb_width, fb_stride, fb_height, 1.0f);
|
||||
vkCmdEndRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer());
|
||||
|
||||
// Prepare the readback texture for copying.
|
||||
StagingTexture2D* readback_texture = PrepareFrameDumpImage(width, height, ticks);
|
||||
if (!readback_texture)
|
||||
|
@ -1042,10 +1044,10 @@ void Renderer::BlitScreen(VkRenderPass render_pass, const TargetRectangle& dst_r
|
|||
const TargetRectangle& src_rect, TargetSize src_size, const Texture2D* src_tex, const Texture2D* src_depth_tex,
|
||||
const TargetSize& dst_size, Texture2D* dst_texture, float Gamma)
|
||||
{
|
||||
OldBlitScreen(render_pass, dst_rect, src_rect, src_tex, true);
|
||||
return;
|
||||
//OldBlitScreen(render_pass, dst_rect, src_rect, src_tex, true);
|
||||
//return;
|
||||
//Disable post proccessing still a work in progress
|
||||
/*
|
||||
|
||||
if (g_ActiveConfig.iStereoMode == STEREO_SBS || g_ActiveConfig.iStereoMode == STEREO_TAB)
|
||||
{
|
||||
TargetRectangle left_rect;
|
||||
|
@ -1062,7 +1064,6 @@ void Renderer::BlitScreen(VkRenderPass render_pass, const TargetRectangle& dst_r
|
|||
m_post_processor->BlitScreen(dst_rect, dst_size, reinterpret_cast<uintptr_t>(dst_texture),
|
||||
src_rect, src_size, reinterpret_cast<uintptr_t>(src_tex), reinterpret_cast<uintptr_t>(src_depth_tex), 0, Gamma);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
bool Renderer::ResizeFrameDumpBuffer(u32 new_width, u32 new_height)
|
||||
|
@ -1204,7 +1205,7 @@ void Renderer::CheckForConfigChanges()
|
|||
FilteringMode old_filtering_mode = g_ActiveConfig.eFilteringMode;
|
||||
bool old_use_xfb = g_ActiveConfig.bUseXFB;
|
||||
bool old_use_realxfb = g_ActiveConfig.bUseRealXFB;
|
||||
|
||||
int last_stereo_mode = g_ActiveConfig.iStereoMode;
|
||||
// Copy g_Config to g_ActiveConfig.
|
||||
// NOTE: This can potentially race with the UI thread, however if it does, the changes will be
|
||||
// delayed until the next time CheckForConfigChanges is called.
|
||||
|
@ -1218,6 +1219,11 @@ void Renderer::CheckForConfigChanges()
|
|||
bool use_xfb_changed = old_use_xfb != g_ActiveConfig.bUseXFB;
|
||||
bool use_realxfb_changed = old_use_realxfb != g_ActiveConfig.bUseRealXFB;
|
||||
|
||||
if (last_stereo_mode != g_ActiveConfig.iStereoMode)
|
||||
{
|
||||
m_post_processor->SetReloadFlag();
|
||||
}
|
||||
|
||||
// Update texture cache settings with any changed options.
|
||||
TextureCache::GetInstance()->OnConfigChanged(g_ActiveConfig);
|
||||
|
||||
|
@ -1257,6 +1263,10 @@ void Renderer::CheckForConfigChanges()
|
|||
// Wipe sampler cache if force texture filtering or anisotropy changes.
|
||||
if (anisotropy_changed || filtering_changed)
|
||||
ResetSamplerStates();
|
||||
|
||||
// if the configuration has changed, reload post processor (can fail, which will deactivate it)
|
||||
if (m_post_processor->RequiresReload())
|
||||
m_post_processor->ReloadShaders();
|
||||
}
|
||||
|
||||
void Renderer::OnSwapChainResized()
|
||||
|
|
|
@ -90,12 +90,13 @@ GetVulkanRasterizationState(const RasterizationState& state)
|
|||
static VkPipelineMultisampleStateCreateInfo
|
||||
GetVulkanMultisampleState(const MultisamplingState& state)
|
||||
{
|
||||
u32 samples = std::max(state.samples.Value(), 1u);
|
||||
return {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
|
||||
nullptr, // const void* pNext
|
||||
0, // VkPipelineMultisampleStateCreateFlags flags
|
||||
static_cast<VkSampleCountFlagBits>(
|
||||
state.samples.Value()), // VkSampleCountFlagBits rasterizationSamples
|
||||
samples), // VkSampleCountFlagBits rasterizationSamples
|
||||
state.per_sample_shading, // VkBool32 sampleShadingEnable
|
||||
1.0f, // float minSampleShading
|
||||
nullptr, // const VkSampleMask* pSampleMask;
|
||||
|
|
|
@ -84,6 +84,20 @@ static const char SHADER_HEADER[] = R"(
|
|||
// These were changed in Vulkan
|
||||
#define gl_VertexID gl_VertexIndex
|
||||
#define gl_InstanceID gl_InstanceIndex
|
||||
|
||||
bool all(float2 val) { return (val.x != 0.0) && (val.y != 0.0); }
|
||||
bool all(float3 val) { return (val.x != 0.0) && (val.y != 0.0) && (val.z != 0.0); }
|
||||
bool all(float4 val) { return (val.x != 0.0) && (val.y != 0.0) && (val.z != 0.0) && (val.w != 0.0); }
|
||||
bool all(int2 val) { return (val.x != 0) && (val.y != 0); }
|
||||
bool all(int3 val) { return (val.x != 0) && (val.y != 0) && (val.z != 0); }
|
||||
bool all(int4 val) { return (val.x != 0) && (val.y != 0) && (val.z != 0) && (val.w != 0); }
|
||||
|
||||
bool any(float2 val) { return (val.x != 0.0) || (val.y != 0.0); }
|
||||
bool any(float3 val) { return (val.x != 0.0) || (val.y != 0.0) || (val.z != 0.0); }
|
||||
bool any(float4 val) { return (val.x != 0.0) || (val.y != 0.0) || (val.z != 0.0) || (val.w != 0.0); }
|
||||
bool any(int2 val) { return (val.x != 0) || (val.y != 0); }
|
||||
bool any(int3 val) { return (val.x != 0) || (val.y != 0) || (val.z != 0); }
|
||||
bool any(int4 val) { return (val.x != 0) || (val.y != 0) || (val.z != 0) || (val.w != 0); }
|
||||
)";
|
||||
|
||||
static const char COMPUTE_SHADER_HEADER[] = R"(
|
||||
|
|
|
@ -254,23 +254,35 @@ bool SwapChain::CreateRenderPass()
|
|||
nullptr };
|
||||
|
||||
VkResult res = vkCreateRenderPass(g_vulkan_context->GetDevice(), &present_render_pass_info,
|
||||
nullptr, &m_render_pass);
|
||||
nullptr, &m_render_clear_pass);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkCreateRenderPass (present) failed: ");
|
||||
return false;
|
||||
}
|
||||
present_render_pass_attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
res = vkCreateRenderPass(g_vulkan_context->GetDevice(), &present_render_pass_info,
|
||||
nullptr, &m_render_append_pass);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkCreateRenderPass (present) failed: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SwapChain::DestroyRenderPass()
|
||||
{
|
||||
if (!m_render_pass)
|
||||
return;
|
||||
|
||||
vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_render_pass, nullptr);
|
||||
m_render_pass = VK_NULL_HANDLE;
|
||||
if (m_render_clear_pass)
|
||||
{
|
||||
vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_render_clear_pass, nullptr);
|
||||
m_render_clear_pass = VK_NULL_HANDLE;
|
||||
}
|
||||
if (m_render_append_pass)
|
||||
{
|
||||
vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_render_append_pass, nullptr);
|
||||
m_render_append_pass = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
bool SwapChain::CreateSwapChain()
|
||||
|
@ -400,7 +412,7 @@ bool SwapChain::SetupSwapChainImages()
|
|||
image.texture = Texture2D::CreateFromExistingImage(
|
||||
m_width, m_height, 1, 1, m_surface_format.format, VK_SAMPLE_COUNT_1_BIT,
|
||||
VK_IMAGE_VIEW_TYPE_2D, image.image, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
|
||||
image.texture->AddFramebuffer(m_render_pass, false);
|
||||
image.texture->AddFramebuffer(m_render_clear_pass, false);
|
||||
m_swap_chain_images.emplace_back(std::move(image));
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,8 @@ public:
|
|||
VkSurfaceFormatKHR GetSurfaceFormat() const { return m_surface_format; }
|
||||
bool IsVSyncEnabled() const { return m_vsync_enabled; }
|
||||
VkSwapchainKHR GetSwapChain() const { return m_swap_chain; }
|
||||
VkRenderPass GetRenderPass() const { return m_render_pass; }
|
||||
VkRenderPass GetRenderClearPass() const { return m_render_clear_pass; }
|
||||
VkRenderPass GetRenderAppendPass() const { return m_render_append_pass; }
|
||||
u32 GetWidth() const { return m_width; }
|
||||
u32 GetHeight() const { return m_height; }
|
||||
u32 GetCurrentImageIndex() const { return m_current_swap_chain_image_index; }
|
||||
|
@ -90,7 +91,8 @@ private:
|
|||
std::vector<SwapChainImage> m_swap_chain_images;
|
||||
u32 m_current_swap_chain_image_index = 0;
|
||||
|
||||
VkRenderPass m_render_pass = VK_NULL_HANDLE;
|
||||
VkRenderPass m_render_clear_pass = VK_NULL_HANDLE;
|
||||
VkRenderPass m_render_append_pass = VK_NULL_HANDLE;
|
||||
|
||||
u32 m_width = 0;
|
||||
u32 m_height = 0;
|
||||
|
|
|
@ -33,13 +33,23 @@ namespace Vulkan
|
|||
{
|
||||
TextureCache::TextureCache()
|
||||
{
|
||||
for (size_t i = 0; i < m_render_pass.size(); i++)
|
||||
{
|
||||
m_render_pass[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
m_scaler = std::make_unique<TextureScaler>();
|
||||
}
|
||||
|
||||
TextureCache::~TextureCache()
|
||||
{
|
||||
if (m_render_pass != VK_NULL_HANDLE)
|
||||
vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_render_pass, nullptr);
|
||||
for (size_t i = 0; i < m_render_pass.size(); i++)
|
||||
{
|
||||
if (m_render_pass[i] != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_render_pass[i], nullptr);
|
||||
m_render_pass[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
TextureCache::DeleteShaders();
|
||||
m_scaler.reset();
|
||||
}
|
||||
|
@ -86,14 +96,13 @@ bool TextureCache::Palettize(TCacheEntry* _entry, const TCacheEntry* base_entry)
|
|||
{
|
||||
TCacheEntry* entry = static_cast<TCacheEntry*>(_entry);
|
||||
const TCacheEntry* unconverted = static_cast<const TCacheEntry*>(base_entry);
|
||||
|
||||
m_texture_converter->ConvertTexture(entry, unconverted, m_render_pass, m_pallette, m_pallette_format, m_pallette_size);
|
||||
VKTexture* dst_tex = static_cast<VKTexture*>(_entry->GetColor());
|
||||
m_texture_converter->ConvertTexture(entry, unconverted, GetRenderPass(dst_tex->GetRawTexIdentifier()->GetFormat()), m_pallette, m_pallette_format, m_pallette_size);
|
||||
static_cast<VKTexture*>(base_entry->GetColor())
|
||||
->GetRawTexIdentifier()
|
||||
->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
static_cast<VKTexture*>(_entry->GetColor())
|
||||
->GetRawTexIdentifier()
|
||||
dst_tex->GetRawTexIdentifier()
|
||||
->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
return true;
|
||||
|
@ -168,7 +177,7 @@ std::unique_ptr<HostTexture> TextureCache::CreateTexture(const TextureConfig& co
|
|||
|
||||
bool TextureCache::CreateRenderPasses()
|
||||
{
|
||||
static constexpr VkAttachmentDescription update_attachment = {
|
||||
VkAttachmentDescription update_attachment = {
|
||||
0,
|
||||
TEXTURECACHE_TEXTURE_FORMAT,
|
||||
VK_SAMPLE_COUNT_1_BIT,
|
||||
|
@ -203,7 +212,42 @@ bool TextureCache::CreateRenderPasses()
|
|||
};
|
||||
|
||||
VkResult res = vkCreateRenderPass(g_vulkan_context->GetDevice(), &update_info, nullptr,
|
||||
&m_render_pass);
|
||||
&m_render_pass[0]);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkCreateRenderPass failed: ");
|
||||
return false;
|
||||
}
|
||||
update_attachment.format = VK_FORMAT_D32_SFLOAT;
|
||||
res = vkCreateRenderPass(g_vulkan_context->GetDevice(), &update_info, nullptr,
|
||||
&m_render_pass[1]);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkCreateRenderPass failed: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
update_attachment.format = VK_FORMAT_R32_SFLOAT;
|
||||
res = vkCreateRenderPass(g_vulkan_context->GetDevice(), &update_info, nullptr,
|
||||
&m_render_pass[2]);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkCreateRenderPass failed: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
update_attachment.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
res = vkCreateRenderPass(g_vulkan_context->GetDevice(), &update_info, nullptr,
|
||||
&m_render_pass[3]);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkCreateRenderPass failed: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
update_attachment.format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
res = vkCreateRenderPass(g_vulkan_context->GetDevice(), &update_info, nullptr,
|
||||
&m_render_pass[4]);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkCreateRenderPass failed: ");
|
||||
|
@ -268,7 +312,7 @@ void TextureCache::CopyEFBToCacheEntry(
|
|||
|
||||
UtilityShaderDraw draw(
|
||||
command_buffer, g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_PUSH_CONSTANT),
|
||||
m_render_pass, g_shader_cache->GetPassthroughVertexShader(),
|
||||
GetRenderPass(texture->GetRawTexIdentifier()->GetFormat()), g_shader_cache->GetPassthroughVertexShader(),
|
||||
g_shader_cache->GetPassthroughGeometryShader(),
|
||||
is_depth_copy ? m_efb_depth_to_tex_shader : m_efb_color_to_tex_shader);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
@ -52,9 +53,25 @@ public:
|
|||
{
|
||||
return m_texture_converter.get();
|
||||
}
|
||||
VkRenderPass GetRenderPass() const
|
||||
VkRenderPass GetRenderPass(VkFormat fmt = VK_FORMAT_R8G8B8A8_UNORM) const
|
||||
{
|
||||
return m_render_pass;
|
||||
if (fmt == VK_FORMAT_D32_SFLOAT)
|
||||
{
|
||||
return m_render_pass[1];
|
||||
}
|
||||
else if (fmt == VK_FORMAT_R32_SFLOAT)
|
||||
{
|
||||
return m_render_pass[2];
|
||||
}
|
||||
else if (fmt == VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
{
|
||||
return m_render_pass[3];
|
||||
}
|
||||
else if (fmt == VK_FORMAT_R32G32B32A32_SFLOAT)
|
||||
{
|
||||
return m_render_pass[4];
|
||||
}
|
||||
return m_render_pass[0];
|
||||
}
|
||||
VkShaderModule GetCopyShader() const
|
||||
{
|
||||
|
@ -67,7 +84,7 @@ public:
|
|||
private:
|
||||
bool CreateRenderPasses();
|
||||
|
||||
VkRenderPass m_render_pass = VK_NULL_HANDLE;
|
||||
std::array<VkRenderPass, 5> m_render_pass;
|
||||
|
||||
std::unique_ptr<StreamBuffer> m_texture_upload_buffer;
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ VkFormat GetVkFormatForHostTextureFormat(HostTextureFormat format)
|
|||
VK_FORMAT_BC2_UNORM_BLOCK,//PC_TEX_FMT_DXT3
|
||||
VK_FORMAT_BC3_UNORM_BLOCK,//PC_TEX_FMT_DXT5
|
||||
VK_FORMAT_BC7_UNORM_BLOCK,//PC_TEX_FMT_BPTC
|
||||
VK_FORMAT_R32_SFLOAT,//PC_TEX_FMT_DEPTH_FLOAT
|
||||
VK_FORMAT_D32_SFLOAT,//PC_TEX_FMT_DEPTH_FLOAT
|
||||
VK_FORMAT_R32_SFLOAT,//PC_TEX_FMT_R_FLOAT
|
||||
VK_FORMAT_R16G16B16A16_SFLOAT,//PC_TEX_FMT_RGBA16_FLOAT
|
||||
VK_FORMAT_R32G32B32A32_SFLOAT,//PC_TEX_FMT_RGBA_FLOAT
|
||||
|
|
|
@ -37,11 +37,16 @@ std::unique_ptr<VKTexture> VKTexture::Create(const TextureConfig& tex_config)
|
|||
// Determine image usage, we need to flag as an attachment if it can be used as a rendertarget.
|
||||
VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
if (tex_config.rendertarget)
|
||||
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
|
||||
// Allocate texture object
|
||||
VkFormat vk_format = Util::GetVkFormatForHostTextureFormat(tex_config.pcformat);
|
||||
if (tex_config.rendertarget)
|
||||
{
|
||||
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
if (Util::IsCompressedFormat(vk_format))
|
||||
{
|
||||
vk_format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
}
|
||||
}
|
||||
auto texture = Texture2D::Create(tex_config.width, tex_config.height, tex_config.levels,
|
||||
tex_config.layers, vk_format, VK_SAMPLE_COUNT_1_BIT,
|
||||
VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_IMAGE_TILING_OPTIMAL, usage);
|
||||
|
@ -53,7 +58,7 @@ std::unique_ptr<VKTexture> VKTexture::Create(const TextureConfig& tex_config)
|
|||
|
||||
if (tex_config.rendertarget)
|
||||
{
|
||||
texture->AddFramebuffer(TextureCache::GetInstance()->GetRenderPass());
|
||||
texture->AddFramebuffer(TextureCache::GetInstance()->GetRenderPass(vk_format));
|
||||
}
|
||||
|
||||
return std::unique_ptr<VKTexture>(new VKTexture(tex_config, std::move(texture)));
|
||||
|
@ -193,7 +198,7 @@ void VKTexture::ScaleTextureRectangle(const MathUtil::Rectangle<int>& dst_rect,
|
|||
|
||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
||||
TextureCache::GetInstance()->GetRenderPass(),
|
||||
TextureCache::GetInstance()->GetRenderPass(m_texture->GetFormat()),
|
||||
g_shader_cache->GetPassthroughVertexShader(),
|
||||
g_shader_cache->GetPassthroughGeometryShader(),
|
||||
TextureCache::GetInstance()->GetCopyShader());
|
||||
|
|
|
@ -231,7 +231,7 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config)
|
|||
config->backend_info.bSupportsClipControl = true; // Assumed support.
|
||||
config->backend_info.bSupportsMultithreading = true; // Assumed support.
|
||||
config->backend_info.bSupportsValidationLayer = true; // Assumed support.
|
||||
config->backend_info.bSupportsPostProcessing = false; // No support yet.
|
||||
config->backend_info.bSupportsPostProcessing = true;
|
||||
config->backend_info.bSupportsDualSourceBlend = false; // Dependent on features.
|
||||
config->backend_info.bSupportsGeometryShaders = false; // Dependent on features.
|
||||
config->backend_info.bSupportsGSInstancing = false; // Dependent on features.
|
||||
|
@ -249,7 +249,6 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config)
|
|||
config->backend_info.bSupportsScaling = false;
|
||||
config->backend_info.bSupportsPixelLighting = true;
|
||||
config->backend_info.bNeedBlendIndices = false;
|
||||
config->backend_info.bSupportsPostProcessing = false;
|
||||
config->backend_info.bSupportsNormalMaps = true;
|
||||
config->backend_info.bSupportsInternalResolutionFrameDumps = true;
|
||||
config->backend_info.bSupportsAsyncShaderCompilation = false;
|
||||
|
|
|
@ -1866,12 +1866,12 @@ void PostProcessor::DrawStereoBuffers(const TargetRectangle& dst_rect, const Tar
|
|||
|
||||
const std::string PostProcessor::s_post_fragment_header_ogl = R"(
|
||||
// Depth value is not inverted for GL
|
||||
#define DEPTH_VALUE(val) (val)
|
||||
#define DEPTH_VALUE(val) (%s(val))
|
||||
// Shader inputs/outputs
|
||||
SAMPLER_BINDING(9) uniform sampler2DArray pp_inputs[8];
|
||||
in float2 v_source_uv;
|
||||
in float2 v_target_uv;
|
||||
flat in float v_layer;
|
||||
SAMPLER_BINDING(%i) uniform sampler2DArray pp_inputs[8];
|
||||
%sin float2 v_source_uv;
|
||||
%sin float2 v_target_uv;
|
||||
%sflat in float v_layer;
|
||||
out float4 ocol0;
|
||||
// Input sampling wrappers. Has to be a macro because the array index must be a constant expression.
|
||||
#define SampleInput(index) (texture(pp_inputs[index], float3(v_source_uv, v_layer)))
|
||||
|
@ -1931,6 +1931,50 @@ float4 SampleInputBicubicLocation3(float2 location)
|
|||
SampleInputLocation(3, texCoord.zw) * scalingFactor.w;
|
||||
}
|
||||
|
||||
float4 SampleInputBicubicLocation4(float2 location)
|
||||
{
|
||||
float4 scalingFactor;
|
||||
float4 texCoord = GetBicubicSampleLocation(4, location, scalingFactor);
|
||||
return
|
||||
SampleInputLocation(4, texCoord.xy) * scalingFactor.x +
|
||||
SampleInputLocation(4, texCoord.zy) * scalingFactor.y +
|
||||
SampleInputLocation(4, texCoord.xw) * scalingFactor.z +
|
||||
SampleInputLocation(4, texCoord.zw) * scalingFactor.w;
|
||||
}
|
||||
|
||||
float4 SampleInputBicubicLocation5(float2 location)
|
||||
{
|
||||
float4 scalingFactor;
|
||||
float4 texCoord = GetBicubicSampleLocation(5, location, scalingFactor);
|
||||
return
|
||||
SampleInputLocation(5, texCoord.xy) * scalingFactor.x +
|
||||
SampleInputLocation(5, texCoord.zy) * scalingFactor.y +
|
||||
SampleInputLocation(5, texCoord.xw) * scalingFactor.z +
|
||||
SampleInputLocation(5, texCoord.zw) * scalingFactor.w;
|
||||
}
|
||||
|
||||
float4 SampleInputBicubicLocation6(float2 location)
|
||||
{
|
||||
float4 scalingFactor;
|
||||
float4 texCoord = GetBicubicSampleLocation(6, location, scalingFactor);
|
||||
return
|
||||
SampleInputLocation(6, texCoord.xy) * scalingFactor.x +
|
||||
SampleInputLocation(6, texCoord.zy) * scalingFactor.y +
|
||||
SampleInputLocation(6, texCoord.xw) * scalingFactor.z +
|
||||
SampleInputLocation(6, texCoord.zw) * scalingFactor.w;
|
||||
}
|
||||
|
||||
float4 SampleInputBicubicLocation7(float2 location)
|
||||
{
|
||||
float4 scalingFactor;
|
||||
float4 texCoord = GetBicubicSampleLocation(7, location, scalingFactor);
|
||||
return
|
||||
SampleInputLocation(7, texCoord.xy) * scalingFactor.x +
|
||||
SampleInputLocation(7, texCoord.zy) * scalingFactor.y +
|
||||
SampleInputLocation(7, texCoord.xw) * scalingFactor.z +
|
||||
SampleInputLocation(7, texCoord.zw) * scalingFactor.w;
|
||||
}
|
||||
|
||||
float4 SampleInputBicubic0()
|
||||
{
|
||||
return SampleInputBicubicLocation0(GetCoordinates());
|
||||
|
@ -1951,8 +1995,96 @@ float4 SampleInputBicubic3()
|
|||
return SampleInputBicubicLocation3(GetCoordinates());
|
||||
}
|
||||
|
||||
#define SampleInputBicubic(idx) SampleInputBicubic##idx()
|
||||
#define SampleInputBicubicLocation(idx, location) SampleInputBicubicLocation##idx(location)
|
||||
float4 SampleInputBicubic4()
|
||||
{
|
||||
return SampleInputBicubicLocation4(GetCoordinates());
|
||||
}
|
||||
|
||||
float4 SampleInputBicubic5()
|
||||
{
|
||||
return SampleInputBicubicLocation5(GetCoordinates());
|
||||
}
|
||||
|
||||
float4 SampleInputBicubic6()
|
||||
{
|
||||
return SampleInputBicubicLocation6(GetCoordinates());
|
||||
}
|
||||
|
||||
float4 SampleInputBicubic7()
|
||||
{
|
||||
return SampleInputBicubicLocation7(GetCoordinates());
|
||||
}
|
||||
|
||||
float4 SampleInputBicubic(int idx)
|
||||
{
|
||||
if(idx == 0)
|
||||
{
|
||||
return SampleInputBicubic0();
|
||||
}
|
||||
else if(idx == 1)
|
||||
{
|
||||
return SampleInputBicubic1();
|
||||
}
|
||||
else if(idx == 2)
|
||||
{
|
||||
return SampleInputBicubic2();
|
||||
}
|
||||
else if(idx == 3)
|
||||
{
|
||||
return SampleInputBicubic3();
|
||||
}
|
||||
else if(idx == 4)
|
||||
{
|
||||
return SampleInputBicubic4();
|
||||
}
|
||||
else if(idx == 5)
|
||||
{
|
||||
return SampleInputBicubic5();
|
||||
}
|
||||
else if(idx == 6)
|
||||
{
|
||||
return SampleInputBicubic6();
|
||||
}
|
||||
else
|
||||
{
|
||||
return SampleInputBicubic7();
|
||||
}
|
||||
}
|
||||
float4 SampleInputBicubicLocation(int idx, float2 location)
|
||||
{
|
||||
if(idx == 0)
|
||||
{
|
||||
return SampleInputBicubicLocation0(location);
|
||||
}
|
||||
else if(idx == 1)
|
||||
{
|
||||
return SampleInputBicubicLocation1(location);
|
||||
}
|
||||
else if(idx == 2)
|
||||
{
|
||||
return SampleInputBicubicLocation2(location);
|
||||
}
|
||||
else if(idx == 3)
|
||||
{
|
||||
return SampleInputBicubicLocation3(location);
|
||||
}
|
||||
else if(idx == 4)
|
||||
{
|
||||
return SampleInputBicubicLocation4(location);
|
||||
}
|
||||
else if(idx == 5)
|
||||
{
|
||||
return SampleInputBicubicLocation5(location);
|
||||
}
|
||||
else if(idx == 6)
|
||||
{
|
||||
return SampleInputBicubicLocation6(location);
|
||||
}
|
||||
else
|
||||
{
|
||||
return SampleInputBicubicLocation7(location);
|
||||
}
|
||||
}
|
||||
|
||||
float4 SampleBicubicLocation(float2 location)
|
||||
{
|
||||
|
@ -1998,6 +2130,10 @@ float4 SampleBicubic()
|
|||
SampleInputLocation(COLOR_BUFFER_INPUT_INDEX, texCoord.zw) * scalingFactor.w;
|
||||
}
|
||||
|
||||
// Option check macro
|
||||
#define GetOption(x) (conf_options.x)
|
||||
#define OptionEnabled(x) ((conf_options.x) != 0)
|
||||
|
||||
)";
|
||||
|
||||
const std::string PostProcessor::s_post_fragment_header_d3d = R"(
|
||||
|
@ -2061,6 +2197,9 @@ float4 SampleBicubic()
|
|||
return SampleInputBicubicLocation(COLOR_BUFFER_INPUT_INDEX, GetCoordinates());
|
||||
}
|
||||
|
||||
// Option check macro
|
||||
#define GetOption(x) (o_##x)
|
||||
#define OptionEnabled(x) ((o_##x) != 0)
|
||||
)";
|
||||
|
||||
const std::string PostProcessor::s_post_fragment_header_common = R"(
|
||||
|
@ -2210,16 +2349,13 @@ float4 GetBicubicSampleLocation(int idx, float2 location, out float4 scalingFact
|
|||
}
|
||||
|
||||
#define SetOutput(color) ocol0 = color
|
||||
// Option check macro
|
||||
#define GetOption(x) (o_##x)
|
||||
#define OptionEnabled(x) ((o_##x) != 0)
|
||||
)";
|
||||
|
||||
void PostProcessor::GetUniformBufferShaderSource(API_TYPE api, const PostProcessingShaderConfiguration* config, std::string& shader_source, bool includeconfig)
|
||||
{
|
||||
// Constant block
|
||||
if (api == API_OPENGL || api == API_VULKAN)
|
||||
shader_source += "UBO_BINDING(std140, 1) uniform PostProcessingConstants {\n";
|
||||
shader_source += StringFromFormat("UBO_BINDING(std140, %i) uniform PostProcessingConstants {\n", api == API_VULKAN ? 2 : 1);
|
||||
else if (api == API_D3D11)
|
||||
shader_source += "cbuffer PostProcessingConstants : register(b0) {\n";
|
||||
|
||||
|
@ -2240,11 +2376,13 @@ void PostProcessor::GetUniformBufferShaderSource(API_TYPE api, const PostProcess
|
|||
return;
|
||||
}
|
||||
bool bufferpacking = false;
|
||||
std::string prefix = "";
|
||||
// User options
|
||||
if (api == API_OPENGL || api == API_VULKAN)
|
||||
shader_source += "UBO_BINDING(std140, 2) uniform ConfigurationConstants {\n";
|
||||
shader_source += StringFromFormat("UBO_BINDING(std140, %i) uniform ConfigurationConstants {\n", api == API_VULKAN ? 1 : 2);
|
||||
else if (api == API_D3D11)
|
||||
{
|
||||
prefix = "o_";
|
||||
bufferpacking = true;
|
||||
shader_source += "cbuffer ConfigurationConstants : register(b1) {\n";
|
||||
}
|
||||
|
@ -2289,24 +2427,24 @@ void PostProcessor::GetUniformBufferShaderSource(API_TYPE api, const PostProcess
|
|||
|
||||
if (it.second.m_type == POST_PROCESSING_OPTION_TYPE_BOOL)
|
||||
{
|
||||
shader_source += StringFromFormat("\tint o_%s;\n", it.first.c_str());
|
||||
shader_source += StringFromFormat("\tint %s%s;\n", prefix.c_str(), it.first.c_str());
|
||||
}
|
||||
else if (it.second.m_type == POST_PROCESSING_OPTION_TYPE_INTEGER)
|
||||
{
|
||||
count = static_cast<u32>(it.second.m_integer_values.size());
|
||||
|
||||
if (count == 1)
|
||||
shader_source += StringFromFormat("\tint o_%s;\n", it.first.c_str());
|
||||
shader_source += StringFromFormat("\tint %s%s;\n", prefix.c_str(), it.first.c_str());
|
||||
else
|
||||
shader_source += StringFromFormat("\tint%d o_%s;\n", count, it.first.c_str());
|
||||
shader_source += StringFromFormat("\tint%d %s%s;\n", count, prefix.c_str(), it.first.c_str());
|
||||
}
|
||||
else if (it.second.m_type == POST_PROCESSING_OPTION_TYPE_FLOAT)
|
||||
{
|
||||
count = static_cast<u32>(it.second.m_float_values.size());
|
||||
if (count == 1)
|
||||
shader_source += StringFromFormat("\tfloat o_%s;\n", it.first.c_str());
|
||||
shader_source += StringFromFormat("\tfloat %s%s;\n", prefix.c_str(), it.first.c_str());
|
||||
else
|
||||
shader_source += StringFromFormat("\tfloat%d o_%s;\n", count, it.first.c_str());
|
||||
shader_source += StringFromFormat("\tfloat%d %s%s;\n", count, prefix.c_str(), it.first.c_str());
|
||||
}
|
||||
if (!bufferpacking)
|
||||
{
|
||||
|
@ -2316,7 +2454,7 @@ void PostProcessor::GetUniformBufferShaderSource(API_TYPE api, const PostProcess
|
|||
}
|
||||
|
||||
// End constant block
|
||||
shader_source += "};\n";
|
||||
shader_source += StringFromFormat("}%s;\n", api == API_D3D11 ? "" : " conf_options");
|
||||
}
|
||||
|
||||
std::string PostProcessor::GetCommonFragmentShaderSource(API_TYPE api, const PostProcessingShaderConfiguration* config, int texture_register_start)
|
||||
|
@ -2324,7 +2462,12 @@ std::string PostProcessor::GetCommonFragmentShaderSource(API_TYPE api, const Pos
|
|||
std::string shader_source;
|
||||
if (api == API_OPENGL || api == API_VULKAN)
|
||||
{
|
||||
shader_source += s_post_fragment_header_ogl;
|
||||
shader_source += StringFromFormat(s_post_fragment_header_ogl.c_str(),
|
||||
api == API_VULKAN ? "1.0f - " : "",
|
||||
texture_register_start,
|
||||
api == API_VULKAN ? "layout(location = 0) " : "",
|
||||
api == API_VULKAN ? "layout(location = 1) " : "",
|
||||
api == API_VULKAN ? "layout(location = 2) " : "") ;
|
||||
}
|
||||
else if (api == API_D3D11)
|
||||
{
|
||||
|
@ -2384,7 +2527,7 @@ std::string PostProcessor::GetPassFragmentShaderSource(
|
|||
}
|
||||
|
||||
// API-specific wrapper
|
||||
if (api == API_OPENGL)
|
||||
if (api != API_D3D11)
|
||||
{
|
||||
// No entry point? This pass should perform a copy.
|
||||
if (pass->entry_point.empty())
|
||||
|
@ -2392,7 +2535,7 @@ std::string PostProcessor::GetPassFragmentShaderSource(
|
|||
else if (pass->entry_point != "main")
|
||||
shader_source += StringFromFormat("void main() { %s(); }\n", pass->entry_point.c_str());
|
||||
}
|
||||
else if (api == API_D3D11)
|
||||
else
|
||||
{
|
||||
shader_source += "void passmain(in float4 in_pos : SV_Position,\n"
|
||||
" in float2 in_srcTexCoord : TEXCOORD0,\n"
|
||||
|
|
Loading…
Reference in a new issue