Implement post processing for Vulkan back end

This commit is contained in:
Rodolfo Bogado 2017-12-09 23:52:46 -03:00
parent 8dc706d983
commit b94fda8e1e
19 changed files with 590 additions and 287 deletions

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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))
{

View file

@ -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)) {

View file

@ -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" : ""

View file

@ -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);
}
}
}

View file

@ -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());

View file

@ -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()

View file

@ -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;

View file

@ -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"(

View file

@ -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));
}

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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());

View file

@ -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;

View file

@ -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"