diff --git a/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass1.slang b/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass1.slang new file mode 100644 index 0000000..17d09b9 --- /dev/null +++ b/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass1.slang @@ -0,0 +1,247 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +/* + + Hyllian's xBR MultiLevel4 Shader - Pass1 + + Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +#define round(X) floor((X)+0.5) +#define TEX(dx,dy) texture(Source, vTexCoord+vec2((dx),(dy))*t1).rgb + +const float cf2 = 2.0; +const float cf3 = 4.0; +const float cf4 = 4.0; +const vec4 eq_thresholdold = vec4(15.0, 15.0, 15.0, 15.0); +const vec4 eq_threshold = vec4( 2.0, 2.0, 2.0, 2.0); +const vec4 eq_threshold3 = vec4(25.0, 25.0, 25.0, 25.0); +const vec3 Yuv_weight = vec3(4.0, 1.0, 2.0); +const mat3x3 yuv = mat3x3(0.299, 0.587, 0.114, -0.169, -0.331, 0.499, 0.499, -0.418, -0.0813); +const mat3x3 yuvT = mat3x3(0.299, -0.169, 0.499, + 0.587, -0.331, -0.418, + 0.114, 0.499, -0.0813); +const mat3x3 yuv_weighted = mat3x3(Yuv_weight.x*yuv[0], Yuv_weight.y*yuv[1], Yuv_weight.z*yuv[2]); +const vec4 maximo = vec4(255.0f, 255.0f, 255.0f, 255.0f); + +vec4 df(vec4 A, vec4 B) +{ + return vec4(abs(A-B)); +} + +bvec4 rd(vec4 A, vec4 B, vec4 C, vec4 D) +{ + return (greaterThan(df(C,D)/(df(A,B)+0.000000001) , vec4(2.0))); +} + +bvec4 id(vec4 A, vec4 B, vec4 C, vec4 D) +{ + return greaterThan(df(C,D) , df(A,B)); +} + +vec4 remapTo01(vec4 v, vec4 high) +{ + return (v/high); +} + +bvec4 eq(vec4 A, vec4 B) +{ + return lessThan(df(A, B) , eq_threshold); +} + +bvec4 eq3(vec4 A, vec4 B) +{ + return lessThan(df(A, B) , eq_threshold3); +} + +vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h) +{ + return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h)); +} + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; +layout(location = 1) out vec2 t1; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; + + float dx = params.SourceSize.z; + float dy = params.SourceSize.w; + + // A3 B3 C3 + // A1 B1 C1 + //A2 A0 A B C C4 C6 + //D2 D0 D E F F4 F6 + //G2 G0 G H I I4 I6 + // G5 H5 I5 + // G7 H7 I7 + + t1 = vec2(dx, dy); // F H +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 t1; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void main() +{ + bvec4 edr0, edr, edr_left, edr_up, edr3_left, edr3_up, edr4_left, edr4_up; // edr = edge detection rule + bvec4 interp_restriction_lv1, interp_restriction_lv2_left, interp_restriction_lv2_up; + bvec4 interp_restriction_lv3_left, interp_restriction_lv3_up; + bvec4 interp_restriction_lv4_left, interp_restriction_lv4_up; + + vec3 A3 = TEX(-1,-3); + vec3 B3 = TEX( 0,-3); + vec3 C3 = TEX( 1,-3); + vec3 A1 = TEX(-1,-2); + vec3 B1 = TEX( 0,-2); + vec3 C1 = TEX( 1,-2); + vec3 A2 = TEX(-3,-1); + vec3 A0 = TEX(-2,-1); + vec3 A = TEX(-1,-1); + vec3 B = TEX( 0,-1); + vec3 C = TEX( 1,-1); + vec3 C4 = TEX( 2,-1); + vec3 C6 = TEX( 3,-1); + vec3 D2 = TEX(-3, 0); + vec3 D0 = TEX(-2, 0); + vec3 D = TEX(-1, 0); + vec3 E = TEX( 0, 0); + vec3 F = TEX( 1, 0); + vec3 F4 = TEX( 2, 0); + vec3 F6 = TEX( 3, 0); + vec3 G2 = TEX(-3, 1); + vec3 G0 = TEX(-2, 1); + vec3 G = TEX(-1, 1); + vec3 H = TEX( 0, 1); + vec3 I = TEX( 1, 1); + vec3 I4 = TEX( 2, 1); + vec3 I6 = TEX( 3, 1); + vec3 G5 = TEX(-1, 2); + vec3 H5 = TEX( 0, 2); + vec3 I5 = TEX( 1, 2); + vec3 G7 = TEX(-1, 3); + vec3 H7 = TEX( 0, 3); + vec3 I7 = TEX( 1, 3); + + mat4x3 bdhf = yuvT * mat4x3(B, D, H, F); + bdhf = mat4x3(abs(bdhf[0]), abs(bdhf[1]), abs(bdhf[2]), abs(bdhf[3])); + vec4 b = Yuv_weight * bdhf; + + bdhf = yuvT * mat4x3(C, A, G, I); + bdhf = mat4x3(abs(bdhf[0]), abs(bdhf[1]), abs(bdhf[2]), abs(bdhf[3])); + vec4 c = Yuv_weight * bdhf; + + bdhf = yuvT * mat4x3(E, E, E, E); + bdhf = mat4x3(abs(bdhf[0]), abs(bdhf[1]), abs(bdhf[2]), abs(bdhf[3])); + vec4 e = Yuv_weight * bdhf; + + vec4 d = b.yzwx; + vec4 f = b.wxyz; + vec4 g = c.zwxy; + vec4 h = b.zwxy; + vec4 i = c.wxyz; + + bdhf = yuvT * mat4x3(I4, C1, A0, G5); + bdhf = mat4x3(abs(bdhf[0]), abs(bdhf[1]), abs(bdhf[2]), abs(bdhf[3])); + vec4 i4 = Yuv_weight * bdhf; + + bdhf = yuvT * mat4x3(I5, C4, A1, G0); + bdhf = mat4x3(abs(bdhf[0]), abs(bdhf[1]), abs(bdhf[2]), abs(bdhf[3])); + vec4 i5 = Yuv_weight * bdhf; + + bdhf = yuvT * mat4x3(H5, F4, B1, D0); + bdhf = mat4x3(abs(bdhf[0]), abs(bdhf[1]), abs(bdhf[2]), abs(bdhf[3])); + vec4 h5 = Yuv_weight * bdhf; + + vec4 f4 = h5.yzwx; + + vec4 c1 = i4.yzwx; + vec4 g0 = i5.wxyz; + vec4 b1 = h5.zwxy; + vec4 d0 = h5.wxyz; + + bdhf = yuvT * mat4x3(I6, C3, A2, G7); + bdhf = mat4x3(abs(bdhf[0]), abs(bdhf[1]), abs(bdhf[2]), abs(bdhf[3])); + vec4 i6 = Yuv_weight * bdhf; + + bdhf = yuvT * mat4x3(I7, C6, A3, G2); + bdhf = mat4x3(abs(bdhf[0]), abs(bdhf[1]), abs(bdhf[2]), abs(bdhf[3])); + vec4 i7 = Yuv_weight * bdhf; + + bdhf = yuvT * mat4x3(H7, F6, B3, D2); + bdhf = mat4x3(abs(bdhf[0]), abs(bdhf[1]), abs(bdhf[2]), abs(bdhf[3])); + vec4 h7 = Yuv_weight * bdhf; + + vec4 f6 = h7.yzwx; + + vec4 c3 = i6.yzwx; + vec4 g2 = i7.wxyz; + vec4 b3 = h7.zwxy; + vec4 d2 = h7.wxyz; + + interp_restriction_lv1 = (notEqual(e,f ) == bvec4(true) && notEqual(e,h) == bvec4(true)) ? bvec4(true) : bvec4(false); + interp_restriction_lv2_left = (notEqual(e,g ) == bvec4(true) && notEqual(d,g) == bvec4(true) && (eq(e, d) == bvec4(true) || eq(h, g) == bvec4(true))) ? bvec4(true) : bvec4(false); + interp_restriction_lv2_up = (notEqual(e,c ) == bvec4(true) && notEqual(b,c) == bvec4(true) && (eq(e, b) == bvec4(true) || eq(f, c) == bvec4(true))) ? bvec4(true) : bvec4(false); + interp_restriction_lv3_left = (notEqual(e,g0) == bvec4(true) && notEqual(d0,g0) == bvec4(true) && (eq(d,d0) == bvec4(true) || eq(g,g0) == bvec4(true))) ? bvec4(true) : bvec4(false); + interp_restriction_lv3_up = (notEqual(e,c1) == bvec4(true) && notEqual(b1,c1) == bvec4(true) && (eq(b,b1) == bvec4(true) || eq(c,c1) == bvec4(true))) ? bvec4(true) : bvec4(false); + interp_restriction_lv4_left = (notEqual(e,g2) == bvec4(true) && notEqual(d2,g2) == bvec4(true) && (eq(d0,d2) == bvec4(true) || eq(g0,g2) == bvec4(true))) ? bvec4(true) : bvec4(false); + interp_restriction_lv4_up = (notEqual(e,c3) == bvec4(true) && notEqual(b3,c3) == bvec4(true) && (eq(b1,b3) == bvec4(true) || eq(c1,c3) == bvec4(true))) ? bvec4(true) : bvec4(false); + + vec4 wd1 = weighted_distance( e, c, g, i, h5, f4, h, f); + vec4 wd2 = weighted_distance( h, d, i5, f, i4, b, e, i); + + edr0 = (lessThanEqual(wd1 , wd2) == bvec4(true) && interp_restriction_lv1 == bvec4(true)) ? bvec4(true) : bvec4(false); + edr = (lessThan(wd1 , wd2) == bvec4(true) && interp_restriction_lv1 == bvec4(true) && ( eq(f,b) == bvec4(false) && id(f,c,f,b) == bvec4(false) || eq(h,d) == bvec4(false) && id(h,g,h,d) == bvec4(false) || eq(e,g) == bvec4(true) || eq(e,c) == bvec4(true))) ? bvec4(true) : bvec4(false); + edr_left = (lessThanEqual((cf2*df(f,g)) , df(h,c)) == bvec4(true) && interp_restriction_lv2_left == bvec4(true) && edr == bvec4(true)) ? bvec4(true) : bvec4(false); + edr_up = (greaterThanEqual(df(f,g) , (cf2*df(h,c))) == bvec4(true) && interp_restriction_lv2_up == bvec4(true) && edr == bvec4(true)) ? bvec4(true) : bvec4(false); + edr3_left = (lessThanEqual((cf3*df(f,g0)) , df(h,c1)) == bvec4(true) && interp_restriction_lv3_left == bvec4(true) && edr_left == bvec4(true)) ? bvec4(true) : bvec4(false); + edr3_up = (greaterThanEqual(df(f,g0) , (cf3*df(h,c1))) == bvec4(true) && interp_restriction_lv3_up == bvec4(true) && edr_up == bvec4(true)) ? bvec4(true) : bvec4(false); + edr4_left = (lessThanEqual((cf4*df(f,g2)) , df(h,c3)) == bvec4(true) && interp_restriction_lv4_left == bvec4(true) && edr3_left == bvec4(true)) ? bvec4(true) : bvec4(false); + edr4_up = (greaterThanEqual(df(f,g2) , (cf4*df(h,c3))) == bvec4(true) && interp_restriction_lv4_up == bvec4(true) && edr3_up == bvec4(true)) ? bvec4(true) : bvec4(false); + + vec4 info; + + info = (edr4_left == bvec4(true) && edr4_up == bvec4(false)) ? vec4(8.0) : ((edr4_up == bvec4(true) && edr4_left == bvec4(false)) ? vec4(7.0) : ((edr3_left == bvec4(true) && edr3_up == bvec4(false)) ? vec4(6.0) : ((edr3_up == bvec4(true) && edr3_left == bvec4(false)) ? vec4(5.0) : ((edr_left == bvec4(true) && edr_up == bvec4(false)) ? vec4(4.0) : ((edr_up == bvec4(true) && edr_left == bvec4(false)) ? vec4(3.0) : (edr == bvec4(true) ? vec4(2.0) : (edr0 == bvec4(true) ? vec4(1.0) : vec4(0.0)))))))); + + FragColor = vec4(remapTo01(info, maximo)); +} \ No newline at end of file diff --git a/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass2.slang b/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass2.slang new file mode 100644 index 0000000..a6ad97c --- /dev/null +++ b/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass2.slang @@ -0,0 +1,235 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +/* + + Hyllian's xBR MultiLevel4 Shader - Pass2 + + Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +#define round(X) floor((X)+0.5) + +const float cf2 = 2.0; +const float cf3 = 4.0; +const float cf4 = 4.0; +const vec4 eq_threshold = vec4(15.0, 15.0, 15.0, 15.0); +const vec4 eq_threshold2 = vec4( 5.0, 5.0, 5.0, 5.0); +const vec4 eq_threshold3 = vec4(25.0, 25.0, 25.0, 25.0); +const float y_weight = 48.0; +const float u_weight = 7.0; +const float v_weight = 6.0; +const mat3x3 yuv = mat3x3(0.299, 0.587, 0.114, -0.169, -0.331, 0.499, 0.499, -0.418, -0.0813); +const mat3x3 yuv_weighted = mat3x3(y_weight*yuv[0], u_weight*yuv[1], v_weight*yuv[2]); +const vec4 maximo = vec4(255.0f, 255.0f, 255.0f, 255.0f); + + +vec4 df(vec4 A, vec4 B) +{ + return vec4(abs(A-B)); +} + +bvec4 rd(vec4 A, vec4 B, vec4 C, vec4 D) +{ + return (greaterThan(df(C,D)/(df(A,B)+0.000000001) , vec4(2.0))); +} + +bvec4 id(vec4 A, vec4 B, vec4 C, vec4 D) +{ + return greaterThan(df(C,D) , df(A,B)); +} + +vec4 remapTo01(vec4 v, vec4 high) +{ + return (v/high); +} + +vec4 remapFrom01(vec4 v, vec4 high) +{ + return round(high*v); +} + +bvec4 eq(vec4 A, vec4 B) +{ + return lessThan(df(A, B) , eq_threshold); +} + +bvec4 eq2(vec4 A, vec4 B) +{ + return lessThan(df(A, B) , eq_threshold2); +} + +bvec4 eq3(vec4 A, vec4 B) +{ + return lessThan(df(A, B) , eq_threshold3); +} + +vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h) +{ + return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h)); +} + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; +layout(location = 1) out vec4 t1; +layout(location = 2) out vec4 t2; +layout(location = 3) out vec4 t3; +layout(location = 4) out vec4 t4; +layout(location = 5) out vec4 t5; +layout(location = 6) out vec4 t6; +layout(location = 7) out vec4 t7; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; + + float dx = params.SourceSize.z; + float dy = params.SourceSize.w; + + // A1 B1 C1 + // A0 A B C C4 + // D0 D E F F4 + // G0 G H I I4 + // G5 H5 I5 + + t1 = vTexCoord.xxxy + vec4( -dx, 0, dx,-2.0*dy); // A1 B1 C1 + t2 = vTexCoord.xxxy + vec4( -dx, 0, dx, -dy); // A B C + t3 = vTexCoord.xxxy + vec4( -dx, 0, dx, 0); // D E F + t4 = vTexCoord.xxxy + vec4( -dx, 0, dx, dy); // G H I + t5 = vTexCoord.xxxy + vec4( -dx, 0, dx, 2.0*dy); // G5 H5 I5 + t6 = vTexCoord.xyyy + vec4(-2.0*dx,-dy, 0, dy); // A0 D0 G0 + t7 = vTexCoord.xyyy + vec4( 2.0*dx,-dy, 0, dy); // C4 F4 I4 +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec4 t1; +layout(location = 2) in vec4 t2; +layout(location = 3) in vec4 t3; +layout(location = 4) in vec4 t4; +layout(location = 5) in vec4 t5; +layout(location = 6) in vec4 t6; +layout(location = 7) in vec4 t7; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D Original; + +void main() +{ + vec4 PA = texture(Source, t2.xw); + vec4 PB = texture(Source, t2.yw); + vec4 PC = texture(Source, t2.zw); + + vec4 PD = texture(Source, t3.xw); + vec4 PE = texture(Source, t3.yw); + vec4 PF = texture(Source, t3.zw); + + vec4 PG = texture(Source, t4.xw); + vec4 PH = texture(Source, t4.yw); + vec4 PI = texture(Source, t4.zw); + + vec3 A1 = texture(Original, t1.xw).rgb; + vec3 B1 = texture(Original, t1.yw).rgb; + vec3 C1 = texture(Original, t1.zw).rgb; + + vec3 A = texture(Original, t2.xw).rgb; + vec3 B = texture(Original, t2.yw).rgb; + vec3 C = texture(Original, t2.zw).rgb; + + vec3 D = texture(Original, t3.xw).rgb; + vec3 E = texture(Original, t3.yw).rgb; + vec3 F = texture(Original, t3.zw).rgb; + + vec3 G = texture(Original, t4.xw).rgb; + vec3 H = texture(Original, t4.yw).rgb; + vec3 I = texture(Original, t4.zw).rgb; + + vec3 G5 = texture(Original, t5.xw).rgb; + vec3 H5 = texture(Original, t5.yw).rgb; + vec3 I5 = texture(Original, t5.zw).rgb; + + vec3 A0 = texture(Original, t6.xy).rgb; + vec3 D0 = texture(Original, t6.xz).rgb; + vec3 G0 = texture(Original, t6.xw).rgb; + + vec3 C4 = texture(Original, t7.xy).rgb; + vec3 F4 = texture(Original, t7.xz).rgb; + vec3 I4 = texture(Original, t7.xw).rgb; + + vec4 b = yuv_weighted[0] * mat4x3(B, D, H, F); + vec4 c = yuv_weighted[0] * mat4x3(C, A, G, I); + vec4 e = yuv_weighted[0] * mat4x3(E, E, E, E); + vec4 d = b.yzwx; + vec4 f = b.wxyz; + vec4 g = c.zwxy; + vec4 h = b.zwxy; + vec4 i = c.wxyz; + + vec4 i4 = yuv_weighted[0] * mat4x3(I4, C1, A0, G5); + vec4 i5 = yuv_weighted[0] * mat4x3(I5, C4, A1, G0); + vec4 h5 = yuv_weighted[0] * mat4x3(H5, F4, B1, D0); + vec4 f4 = h5.yzwx; + + vec4 pe = remapFrom01(PE, maximo); + vec4 pf = remapFrom01(PF, maximo); + vec4 ph = remapFrom01(PH, maximo); + vec4 pb = remapFrom01(PB, maximo); + vec4 pd = remapFrom01(PD, maximo); + + vec4 f2 = vec4(pf.z, pb.w, pd.x, ph.y); + vec4 h2 = vec4(ph.z, pf.w, pb.x, pd.y); + vec4 f1 = vec4(pf.y, pb.z, pd.w, ph.x); + vec4 h3 = vec4(ph.w, pf.x, pb.y, pd.z); + + bvec4 nbrs = (greaterThan(pe.yzwx, vec4(1.0)) == bvec4(true) || greaterThan(pe.wxyz, vec4(1.0)) == bvec4(true)) ? bvec4(true) : bvec4(false); + bvec4 jag1 = (greaterThan(f2, vec4(1.0)) == bvec4(true) || greaterThan(h2, vec4(1.0)) == bvec4(true)) ? bvec4(true) : bvec4(false); + bvec4 jag2 = (greaterThan(f2, vec4(2.0)) == bvec4(true) || greaterThan(h2, vec4(2.0)) == bvec4(true)) ? bvec4(true) : bvec4(false); + bvec4 jag3 = (greaterThan(f2, vec4(4.0)) == bvec4(true) || greaterThan(h2, vec4(4.0)) == bvec4(true)) ? bvec4(true) : bvec4(false); + + pe = (pe == vec4(7.0) || pe == vec4(8.0)) ? ((jag3 == bvec4(true)) ? pe : (pe - float(2.0))) : pe; + pe = (pe == vec4(5.0) || pe == vec4(6.0)) ? ((jag2 == bvec4(true)) ? pe : (pe - float(2.0))) : pe; + + bvec4 jag91 = ((id(h,i,e,h) == bvec4(true) || id(i4,i,f4,i4) == bvec4(true)) && greaterThan(f2 , vec4(1.0)) == bvec4(true) && greaterThan(f1 , vec4(1.0)) == bvec4(true)) ? bvec4(true) : bvec4(false); + bvec4 jag92 = ((id(f,i,e,f) == bvec4(true) || id(i5,i,h5,i5) == bvec4(true)) && greaterThan(h2 , vec4(1.0)) == bvec4(true) && greaterThan(h3 , vec4(1.0)) == bvec4(true)) ? bvec4(true) : bvec4(false); + bvec4 jag93 = ( rd(h,g,e,g) == bvec4(true)) ? bvec4(true) : bvec4(false); + bvec4 jag94 = ( rd(f,c,e,c) == bvec4(true)) ? bvec4(true) : bvec4(false); + bvec4 jag9 = ((jag91 == bvec4(true) && jag93 == bvec4(true) || jag92 == bvec4(true) && jag94 == bvec4(true)) == false) ? bvec4(true) : bvec4(false); + + pe = ((pe == vec4(0.0)) || (nbrs == bvec4(false) || jag1 == bvec4(true)) && jag9 == bvec4(true)) ? pe : vec4(1.0); + + FragColor = vec4(remapTo01(pe, maximo)); +} \ No newline at end of file diff --git a/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass3.slang b/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass3.slang new file mode 100644 index 0000000..7da4321 --- /dev/null +++ b/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass3.slang @@ -0,0 +1,239 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +/* + + Hyllian's xBR MultiLevel4 Shader - Pass3 + + Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +#define round(X) floor((X)+0.5) + +const float coef = 2.0; +const float cf = 4.0; +const float eq_threshold = 15.0; +const float y_weight = 48.0; +const float u_weight = 7.0; +const float v_weight = 6.0; +const mat3x3 yuv = mat3x3(0.299, 0.587, 0.114, -0.169, -0.331, 0.499, 0.499, -0.418, -0.0813); +const mat3x3 yuv_weighted = mat3x3(y_weight*yuv[0], u_weight*yuv[1], v_weight*yuv[2]); +const vec4 maximo = vec4(255.0f, 255.0f, 255.0f, 255.0f); +const vec4 low = vec4(-64.0f, -64.0f, -64.0f, -64.0f); +const vec4 high = vec4( 64.0f, 64.0f, 64.0f, 64.0f); + +const mat2x4 sym_vectors = mat2x4(1, 1, -1, -1, 1, -1, -1, 1); + +// Bx, Ay, C +const vec3 lines[13] = { + vec3( 4.0, 4.0, 4.0), // 0 NL + vec3( 4.0, 4.0, 3.0), // 1 LV0 + vec3( 4.0, 4.0, 2.0), // 2 LV1 + vec3( 8.0, 4.0, 2.0), // 3 LV2u + vec3( 4.0, 8.0, 2.0), // 4 LV2l + vec3(12.0, 4.0, 2.0), // 5 LV3u + vec3( 4.0,12.0, 2.0), // 6 LV3l + vec3(16.0, 4.0, 2.0), // 7 LV4u + vec3( 4.0,16.0, 2.0), // 8 LV4l + vec3(12.0, 4.0, 6.0), // 9 LV3u + vec3( 4.0,12.0, 6.0), // 10 LV3l + vec3(16.0, 4.0, 6.0), // 11 LV4u + vec3( 4.0,16.0, 6.0), // 12 LV4l +}; + +vec4 remapTo01(vec4 v, vec4 low, vec4 high) +{ + return clamp((v - low)/(high-low), 0.0, 1.0); +} + +float remapFrom01(float v, float high) +{ + return round(high*v); +} + + +float df(float A, float B) +{ + return abs(A-B); +} + +bool eq(float A, float B) +{ + return (df(A, B) < eq_threshold); +} + +float weighted_distance(float a, float b, float c, float d, float e, float f, float g, float h) +{ + return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h)); +} + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; +layout(location = 1) out vec4 t1; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; + float dx = params.OriginalSize.z; + float dy = params.OriginalSize.w; + + // A3 B3 C3 + // A1 B1 C1 + //A2 A0 A B C C4 C6 + //D2 D0 D E F F4 F6 + //G2 G0 G H I I4 I6 + // G5 H5 I5 + // G7 H7 I7 + + t1 = vec4(dx, 0, 0, dy); // F H +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec4 t1; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D Original; + +void main() +{ + float px; + + vec2 pos = fract(vTexCoord.xy * params.OriginalSize.xy) - vec2(0.4999, 0.4999); // pos = pixel position + vec2 dir = sign(pos); // dir = pixel direction + + vec2 g1 = dir * ( clamp(-dir.y*dir.x, 0.0, 1.0) * t1.zw + clamp( dir.y*dir.x, 0.0, 1.0) * t1.xy); + vec2 g2 = dir * ( clamp( dir.y*dir.x, 0.0, 1.0) * t1.zw + clamp(-dir.y*dir.x, 0.0, 1.0) * t1.xy); + + vec3 E = texture(Original, vTexCoord ).rgb; + vec3 F = texture(Original, vTexCoord + g1).rgb; + vec3 H = texture(Original, vTexCoord + g2).rgb; + vec3 I = texture(Original, vTexCoord + g1 + g2).rgb; + vec3 F4 = texture(Original, vTexCoord + 2.0 * g1).rgb; + vec3 H5 = texture(Original, vTexCoord + 2.0 * g2).rgb; + + float e = dot(E, yuv_weighted[0]); + float f = dot(F, yuv_weighted[0]); + float h = dot(H, yuv_weighted[0]); + float i = dot(I, yuv_weighted[0]); + float f4 = dot(F4, yuv_weighted[0]); + float h5 = dot(H5, yuv_weighted[0]); + + vec4 icomp = round(clamp(sym_vectors * dir, 0.0, 1.0)); // choose info component + + float infoE = remapFrom01(dot(texture(Source, vTexCoord ), icomp), 255.0f); // retrieve 1st pass info + float infoF = remapFrom01(dot(texture(Source, vTexCoord+g1), icomp), 255.0f); // 1st pass info from neighbor r + float infoH = remapFrom01(dot(texture(Source, vTexCoord+g2), icomp), 255.0f); // 1st pass info from neighbor d + + vec4 lparam; + vec2 addr; + + if (infoF == 8.0) + { + lparam.xyz = lines[12]; + px = ((df(f,f4) <= df(f,i)) == true) ? 1.0 : 0.0; + addr.x = 2*px + clamp(1.0-px, 0.0, 1.0); + addr.y = clamp(1.0-px, 0.0, 1.0); + } + else if (infoH == 7.0) + { + lparam.xyz = lines[11]; + px = ((df(h,h5) <= df(h,i)) == true) ? 1.0 : 0.0; + addr.x = clamp(1.0-px, 0.0, 1.0); + addr.y = 2*px + clamp(1.0-px, 0.0, 1.0); + } + else if (infoF == 6.0) + { + lparam.xyz = lines[10]; + px = ((df(f,f4) <= df(f,i)) == true) ? 1.0 : 0.0; + addr.x = 2*px + clamp(1.0-px, 0.0, 1.0); + addr.y = clamp(1.0-px, 0.0, 1.0); + } + else if (infoH == 5.0) + { + lparam.xyz = lines[9]; + px = ((df(h,h5) <= df(h,i)) == true) ? 1.0 : 0.0; + addr.x = clamp(1.0-px, 0.0, 1.0); + addr.y = 2*px + clamp(1.0-px, 0.0, 1.0); + } + else + { + px = ((df(e,f) <= df(e,h)) == true) ? 1.0 : 0.0; + addr.x = px; + addr.y = clamp(1.0-px, 0.0, 1.0); + + lparam.xyz = (infoE == 8.0) ? lines[8] : ((infoE == 7.0) ? lines[7] : ((infoE == 6.0) ? lines[6] : ((infoE == 5.0) ? lines[5] : ((infoE == 4.0) ? lines[4] : ((infoE == 3.0) ? lines[3] : ((infoE == 2.0) ? lines[2] : ((infoE == 1.0) ? lines[1] : lines[0]))))))); + } + + bool inv = (dir.x*dir.y) < 0.0 ? true : false; + + // Rotate address from relative to absolute. + addr = addr*dir.yx; + addr = inv ? addr.yx : addr; + + // Rotate straight line equation from relative to absolute. + lparam.xy = lparam.xy*dir.yx; + lparam.xy = inv ? lparam.yx : lparam.xy; + + addr.x += 2.0; + addr.y += 2.0; + + lparam.w = addr.x*8.0 + addr.y; + + FragColor = vec4(remapTo01(lparam, low, high)); +} + +/* +19 1 +9 1 +4 0 +2 0 +1 1 +0 0 + +0 0000 ND +1 0001 EDR0 +2 0010 EDR +3 0011 EDRU +4 0100 EDRL +5 0101 EDRU3 +6 0110 EDRL3 + +0 1 2 3 4 +-2 -1 0 1 2 + +*/ \ No newline at end of file diff --git a/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass4.slang b/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass4.slang new file mode 100644 index 0000000..8bc7f97 --- /dev/null +++ b/test/nonfunctional/shaders/xbr-mlv4-multipass/xbr-mlv4-pass4.slang @@ -0,0 +1,177 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +/* + + Hyllian's xBR MultiLevel4 Shader - Pass4 + + Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +#define round(X) floor((X)+0.5) + +const vec3 bin = vec3( 4.0f, 2.0f, 1.0f); +const vec4 low = vec4(-64.0f, -64.0f, -64.0f, -64.0f); +const vec4 high = vec4( 64.0f, 64.0f, 64.0f, 64.0f); + +const mat2x4 sym_vectors = mat2x4(1, 1, -1, -1, 1, -1, -1, 1); + +vec4 remapFrom01(vec4 v, vec4 low, vec4 high) +{ + return round(mix(low, high, v)); +} + +float c_df(vec3 c1, vec3 c2) +{ + vec3 df = abs(c1 - c2); + return df.r + df.g + df.b; +} + + +vec4 unpack_info(float i) +{ + vec4 info; + info.x = round(modf(i/2.0f, i)); + info.y = round(modf(i/2.0f, i)); + info.z = round(modf(i/2.0f, i)); + info.w = i; + + return info; +} + + +float df(float A, float B) +{ + return abs(A-B); +} + +#define GET_PIXEL(PARAM, PIXEL)\ + info = PARAM;\ + ay.z = round( modf( info/2.0f, info ) );\ + ay.y = round( modf( info/2.0f, info ) );\ + ay.x = round( modf( info/2.0f, info ) );\ + ax.z = round( modf( info/2.0f, info ) );\ + ax.y = round( modf( info/2.0f, info ) );\ + ax.x = round( info );\ + iq.x = dot( ax, bin ) - 2.0;\ + iq.y = dot( ay, bin ) - 2.0;\ + PIXEL = texture( Original, vTexCoord + iq.x * t1.xy + iq.y * t1.zw ).xyz;\ + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; +layout(location = 1) out vec4 t1; +layout(location = 2) out float scale_factor; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; + float dx = params.OriginalSize.z; + float dy = params.OriginalSize.w; + + // A3 B3 C3 + // A1 B1 C1 + //A2 A0 A B C C4 C6 + //D2 D0 D E F F4 F6 + //G2 G0 G H I I4 I6 + // G5 H5 I5 + // G7 H7 I7 + t1 = vec4(dx, 0, 0, dy); // F H + scale_factor = params.OutputSize.x * params.OriginalSize.z; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec4 t1; +layout(location = 2) in float scale_factor; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D Original; + +void main() +{ + vec2 fp = fract( vTexCoord * params.OriginalSize.xy ) - vec2( 0.4999, 0.4999 ); // pos = pixel position + + vec2 pxcoord = floor(vTexCoord * params.OriginalSize.xy) * params.OriginalSize.zw; + + vec4 UL = texture(Source, pxcoord + 0.25 * t1.xy + 0.25 * t1.zw ); + vec4 UR = texture(Source, pxcoord + 0.75 * t1.xy + 0.25 * t1.zw ); + vec4 DL = texture(Source, pxcoord + 0.25 * t1.xy + 0.75 * t1.zw ); + vec4 DR = texture(Source, pxcoord + 0.75 * t1.xy + 0.75 * t1.zw ); + + vec4 ulparam = remapFrom01( UL, low, high ); // retrieve 1st pass info + vec4 urparam = remapFrom01( UR, low, high ); // retrieve 1st pass info + vec4 dlparam = remapFrom01( DL, low, high ); // retrieve 1st pass info + vec4 drparam = remapFrom01( DR, low, high ); // retrieve 1st pass info + + vec3 E = texture( Original, vTexCoord ).xyz; + + vec3 ax, ay, PX, PY, PZ, PW; + float info; + vec2 iq; + + GET_PIXEL(ulparam.w, PX); + GET_PIXEL(urparam.w, PY); + GET_PIXEL(dlparam.w, PZ); + GET_PIXEL(drparam.w, PW); + + vec3 fp1 = vec3( fp, -1 ); + + vec3 color; + vec4 fx; + + vec4 inc = vec4(abs(ulparam.x / ulparam.y), abs(urparam.x / urparam.y), abs(dlparam.x / dlparam.y), abs(drparam.x / drparam.y)); + vec4 level = max(inc, 1.0 / inc); + + fx.x = clamp( dot( fp1, ulparam.xyz ) * scale_factor / ( 8 * level.x ) + 0.5 , 0.0, 1.0); + fx.y = clamp( dot( fp1, urparam.xyz ) * scale_factor / ( 8 * level.y ) + 0.5 , 0.0, 1.0); + fx.z = clamp( dot( fp1, dlparam.xyz ) * scale_factor / ( 8 * level.z ) + 0.5 , 0.0, 1.0); + fx.w = clamp( dot( fp1, drparam.xyz ) * scale_factor / ( 8 * level.w ) + 0.5 , 0.0, 1.0); + + vec3 c1, c2, c3, c4; + + c1 = mix( E, PX, fx.x ); + c2 = mix( E, PY, fx.y ); + c3 = mix( E, PZ, fx.z ); + c4 = mix( E, PW, fx.w ); + + color = c1; + color = ( (c_df(c2, E) > c_df(color, E)) ) ? c2 : color; + color = ( (c_df(c3, E) > c_df(color, E)) ) ? c3 : color; + color = ( (c_df(c4, E) > c_df(color, E)) ) ? c4 : color; + + FragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/test/nonfunctional/xbr-mlv4-multipass.slangp b/test/nonfunctional/xbr-mlv4-multipass.slangp new file mode 100644 index 0000000..c485309 --- /dev/null +++ b/test/nonfunctional/xbr-mlv4-multipass.slangp @@ -0,0 +1,32 @@ +shaders = "4" + +shader0 = shaders/xbr-mlv4-multipass/xbr-mlv4-pass1.slang +filter_linear0 = "false" +float_framebuffer0 = "false" +scale_type_x0 = "source" +scale_x0 = "1.000000" +scale_type_y0 = "source" +scale_y0 = "1.000000" +alias0 = "PASS1" + +shader1 = shaders/xbr-mlv4-multipass/xbr-mlv4-pass2.slang +filter_linear1 = "false" +float_framebuffer1 = "false" +scale_type_x1 = "source" +scale_x1 = "1.000000" +scale_type_y1 = "source" +scale_y1 = "1.000000" +alias1 = "PASS2" + +shader2 = shaders/xbr-mlv4-multipass/xbr-mlv4-pass3.slang +filter_linear2 = "false" +float_framebuffer2 = "false" +scale_type_x2 = "source" +scale_x2 = "2.000000" +scale_type_y2 = "source" +scale_y2 = "2.000000" +alias2 = "PASS3" + +shader3 = shaders/xbr-mlv4-multipass/xbr-mlv4-pass4.slang +filter_linear3 = "false" +float_framebuffer3 = "false"