Skip to content

Commit d926f07

Browse files
Restore sgsr1 original version and add edge direction variant
Signed-off-by: Rodrigo Holztrattner <quic_rholztra@quicinc.com>
1 parent 4ea5e8b commit d926f07

2 files changed

Lines changed: 210 additions & 68 deletions

File tree

sgsr/v1/include/glsl/sgsr1_shader_mobile.frag

Lines changed: 34 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//============================================================================================================
44
//
55
//
6-
// Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
6+
// Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
77
// SPDX-License-Identifier: BSD-3-Clause
88
//
99
//============================================================================================================
@@ -23,12 +23,6 @@ precision highp int;
2323
*/
2424
#define OperationMode 1
2525

26-
/*
27-
* If set, will use edge direction to improve visual quality
28-
* Expect a minimal cost increase
29-
*/
30-
// #define UseEdgeDirection
31-
3226
#define EdgeThreshold 8.0/255.0
3327

3428
#define EdgeSharpness 2.0
@@ -60,46 +54,21 @@ float fastLanczos2(float x)
6054
wA *= wA;
6155
return wB*wA;
6256
}
63-
64-
#if defined(UseEdgeDirection)
65-
vec2 weightY(float dx, float dy, float c, vec3 data)
66-
#else
67-
vec2 weightY(float dx, float dy, float c, float data)
68-
#endif
57+
vec2 weightY(float dx, float dy,float c, float std)
6958
{
70-
#if defined(UseEdgeDirection)
71-
float std = data.x;
72-
vec2 dir = data.yz;
73-
74-
float edgeDis = ((dx*dir.y)+(dy*dir.x));
75-
float x = (((dx*dx)+(dy*dy))+((edgeDis*edgeDis)*((clamp(((c*c)*std),0.0,1.0)*0.7)+-1.0)));
76-
#else
77-
float std = data;
7859
float x = ((dx*dx)+(dy* dy))* 0.55 + clamp(abs(c)*std, 0.0, 1.0);
79-
#endif
80-
8160
float w = fastLanczos2(x);
8261
return vec2(w, w * c);
8362
}
8463

85-
vec2 edgeDirection(vec4 left, vec4 right)
86-
{
87-
vec2 dir;
88-
float RxLz = (right.x + (-left.z));
89-
float RwLy = (right.w + (-left.y));
90-
vec2 delta;
91-
delta.x = (RxLz + RwLy);
92-
delta.y = (RxLz + (-RwLy));
93-
float lengthInv = inversesqrt((delta.x * delta.x+ 3.075740e-05) + (delta.y * delta.y));
94-
dir.x = (delta.x * lengthInv);
95-
dir.y = (delta.y * lengthInv);
96-
return dir;
97-
}
98-
9964
void main()
10065
{
66+
int mode = OperationMode;
67+
float edgeThreshold = EdgeThreshold;
68+
float edgeSharpness = EdgeSharpness;
69+
10170
vec4 color;
102-
if(OperationMode == 1)
71+
if(mode == 1)
10372
color.xyz = textureLod(ps0,in_TEXCOORD0.xy,0.0).xyz;
10473
else
10574
color.xyzw = textureLod(ps0,in_TEXCOORD0.xy,0.0).xyzw;
@@ -110,57 +79,54 @@ void main()
11079
yCenter = abs(in_TEXCOORD0.y+-0.5);
11180

11281
//todo: config the SR region based on needs
113-
//if ( OperationMode!=4 && xCenter*xCenter+yCenter*yCenter<=0.4 * 0.4)
114-
if ( OperationMode!=4)
82+
//if ( mode!=4 && xCenter*xCenter+yCenter*yCenter<=0.4 * 0.4)
83+
if ( mode!=4)
11584
{
11685
highp vec2 imgCoord = ((in_TEXCOORD0.xy*ViewportInfo[0].zw)+vec2(-0.5,0.5));
11786
highp vec2 imgCoordPixel = floor(imgCoord);
11887
highp vec2 coord = (imgCoordPixel*ViewportInfo[0].xy);
11988
vec2 pl = (imgCoord+(-imgCoordPixel));
120-
vec4 left = textureGather(ps0,coord, OperationMode);
89+
vec4 left = textureGather(ps0,coord, mode);
12190

122-
float edgeVote = abs(left.z - left.y) + abs(color[OperationMode] - left.y) + abs(color[OperationMode] - left.z) ;
123-
if(edgeVote > EdgeThreshold)
91+
float edgeVote = abs(left.z - left.y) + abs(color[mode] - left.y) + abs(color[mode] - left.z) ;
92+
if(edgeVote > edgeThreshold)
12493
{
12594
coord.x += ViewportInfo[0].x;
12695

127-
vec4 right = textureGather(ps0,coord + highp vec2(ViewportInfo[0].x, 0.0), OperationMode);
96+
vec4 right = textureGather(ps0,coord + highp vec2(ViewportInfo[0].x, 0.0), mode);
12897
vec4 upDown;
129-
upDown.xy = textureGather(ps0,coord + highp vec2(0.0, -ViewportInfo[0].y),OperationMode).wz;
130-
upDown.zw = textureGather(ps0,coord+ highp vec2(0.0, ViewportInfo[0].y), OperationMode).yx;
98+
upDown.xy = textureGather(ps0,coord + highp vec2(0.0, -ViewportInfo[0].y),mode).wz;
99+
upDown.zw = textureGather(ps0,coord+ highp vec2(0.0, ViewportInfo[0].y), mode).yx;
131100

132101
float mean = (left.y+left.z+right.x+right.w)*0.25;
133102
left = left - vec4(mean);
134103
right = right - vec4(mean);
135104
upDown = upDown - vec4(mean);
136-
color.w =color[OperationMode] - mean;
105+
color.w =color[mode] - mean;
137106

138107
float sum = (((((abs(left.x)+abs(left.y))+abs(left.z))+abs(left.w))+(((abs(right.x)+abs(right.y))+abs(right.z))+abs(right.w)))+(((abs(upDown.x)+abs(upDown.y))+abs(upDown.z))+abs(upDown.w)));
139-
float sumMean = 1.014185e+01/sum;
140-
float std = (sumMean*sumMean);
141-
142-
#if defined(UseEdgeDirection)
143-
vec3 data = vec3(std, edgeDirection(left, right));
144-
#else
145-
float data = std;
146-
#endif
147-
vec2 aWY = weightY(pl.x, pl.y+1.0, upDown.x,data);
148-
aWY += weightY(pl.x-1.0, pl.y+1.0, upDown.y,data);
149-
aWY += weightY(pl.x-1.0, pl.y-2.0, upDown.z,data);
150-
aWY += weightY(pl.x, pl.y-2.0, upDown.w,data);
151-
aWY += weightY(pl.x+1.0, pl.y-1.0, left.x,data);
152-
aWY += weightY(pl.x, pl.y-1.0, left.y,data);
153-
aWY += weightY(pl.x, pl.y, left.z,data);
154-
aWY += weightY(pl.x+1.0, pl.y, left.w,data);
155-
aWY += weightY(pl.x-1.0, pl.y-1.0, right.x,data);
156-
aWY += weightY(pl.x-2.0, pl.y-1.0, right.y,data);
157-
aWY += weightY(pl.x-2.0, pl.y, right.z,data);
158-
aWY += weightY(pl.x-1.0, pl.y, right.w,data);
108+
float std = 2.181818/sum;
109+
110+
vec2 aWY = weightY(pl.x, pl.y+1.0, upDown.x,std);
111+
aWY += weightY(pl.x-1.0, pl.y+1.0, upDown.y,std);
112+
aWY += weightY(pl.x-1.0, pl.y-2.0, upDown.z,std);
113+
aWY += weightY(pl.x, pl.y-2.0, upDown.w,std);
114+
aWY += weightY(pl.x+1.0, pl.y-1.0, left.x,std);
115+
aWY += weightY(pl.x, pl.y-1.0, left.y,std);
116+
aWY += weightY(pl.x, pl.y, left.z,std);
117+
aWY += weightY(pl.x+1.0, pl.y, left.w,std);
118+
aWY += weightY(pl.x-1.0, pl.y-1.0, right.x,std);
119+
aWY += weightY(pl.x-2.0, pl.y-1.0, right.y,std);
120+
aWY += weightY(pl.x-2.0, pl.y, right.z,std);
121+
aWY += weightY(pl.x-1.0, pl.y, right.w,std);
159122

160123
float finalY = aWY.y/aWY.x;
124+
161125
float maxY = max(max(left.y,left.z),max(right.x,right.w));
162126
float minY = min(min(left.y,left.z),min(right.x,right.w));
163-
float deltaY = clamp(EdgeSharpness*finalY, minY, maxY) -color.w;
127+
finalY = clamp(edgeSharpness*finalY, minY, maxY);
128+
129+
float deltaY = finalY -color.w;
164130

165131
//smooth high contrast input
166132
deltaY = clamp(deltaY, -23.0 / 255.0, 23.0 / 255.0);
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
#version 300 es
2+
3+
//============================================================================================================
4+
//
5+
//
6+
// Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
7+
// SPDX-License-Identifier: BSD-3-Clause
8+
//
9+
//============================================================================================================
10+
11+
precision mediump float;
12+
precision highp int;
13+
14+
////////////////////////
15+
// USER CONFIGURATION //
16+
////////////////////////
17+
18+
/*
19+
* Operation modes:
20+
* RGBA -> 1
21+
* RGBY -> 3
22+
* LERP -> 4
23+
*/
24+
#define OperationMode 1
25+
26+
/*
27+
* If set, will use edge direction to improve visual quality
28+
* Expect a minimal cost increase
29+
*/
30+
// #define UseEdgeDirection
31+
32+
#define EdgeThreshold 8.0/255.0
33+
34+
#define EdgeSharpness 2.0
35+
36+
// #define UseUniformBlock
37+
38+
////////////////////////
39+
////////////////////////
40+
////////////////////////
41+
42+
#if defined(UseUniformBlock)
43+
layout (set=0, binding = 0) uniform UniformBlock
44+
{
45+
highp vec4 ViewportInfo[1];
46+
};
47+
layout(set = 0, binding = 1) uniform mediump sampler2D ps0;
48+
#else
49+
uniform highp vec4 ViewportInfo[1];
50+
uniform mediump sampler2D ps0;
51+
#endif
52+
53+
layout(location=0) in highp vec4 in_TEXCOORD0;
54+
layout(location=0) out vec4 out_Target0;
55+
56+
float fastLanczos2(float x)
57+
{
58+
float wA = x-4.0;
59+
float wB = x*wA-wA;
60+
wA *= wA;
61+
return wB*wA;
62+
}
63+
64+
#if defined(UseEdgeDirection)
65+
vec2 weightY(float dx, float dy, float c, vec3 data)
66+
#else
67+
vec2 weightY(float dx, float dy, float c, float data)
68+
#endif
69+
{
70+
#if defined(UseEdgeDirection)
71+
float std = data.x;
72+
vec2 dir = data.yz;
73+
74+
float edgeDis = ((dx*dir.y)+(dy*dir.x));
75+
float x = (((dx*dx)+(dy*dy))+((edgeDis*edgeDis)*((clamp(((c*c)*std),0.0,1.0)*0.7)+-1.0)));
76+
#else
77+
float std = data;
78+
float x = ((dx*dx)+(dy* dy))* 0.55 + clamp(abs(c)*std, 0.0, 1.0);
79+
#endif
80+
81+
float w = fastLanczos2(x);
82+
return vec2(w, w * c);
83+
}
84+
85+
vec2 edgeDirection(vec4 left, vec4 right)
86+
{
87+
vec2 dir;
88+
float RxLz = (right.x + (-left.z));
89+
float RwLy = (right.w + (-left.y));
90+
vec2 delta;
91+
delta.x = (RxLz + RwLy);
92+
delta.y = (RxLz + (-RwLy));
93+
float lengthInv = inversesqrt((delta.x * delta.x+ 3.075740e-05) + (delta.y * delta.y));
94+
dir.x = (delta.x * lengthInv);
95+
dir.y = (delta.y * lengthInv);
96+
return dir;
97+
}
98+
99+
void main()
100+
{
101+
vec4 color;
102+
if(OperationMode == 1)
103+
color.xyz = textureLod(ps0,in_TEXCOORD0.xy,0.0).xyz;
104+
else
105+
color.xyzw = textureLod(ps0,in_TEXCOORD0.xy,0.0).xyzw;
106+
107+
highp float xCenter;
108+
xCenter = abs(in_TEXCOORD0.x+-0.5);
109+
highp float yCenter;
110+
yCenter = abs(in_TEXCOORD0.y+-0.5);
111+
112+
//todo: config the SR region based on needs
113+
//if ( OperationMode!=4 && xCenter*xCenter+yCenter*yCenter<=0.4 * 0.4)
114+
if ( OperationMode!=4)
115+
{
116+
highp vec2 imgCoord = ((in_TEXCOORD0.xy*ViewportInfo[0].zw)+vec2(-0.5,0.5));
117+
highp vec2 imgCoordPixel = floor(imgCoord);
118+
highp vec2 coord = (imgCoordPixel*ViewportInfo[0].xy);
119+
vec2 pl = (imgCoord+(-imgCoordPixel));
120+
vec4 left = textureGather(ps0,coord, OperationMode);
121+
122+
float edgeVote = abs(left.z - left.y) + abs(color[OperationMode] - left.y) + abs(color[OperationMode] - left.z) ;
123+
if(edgeVote > EdgeThreshold)
124+
{
125+
coord.x += ViewportInfo[0].x;
126+
127+
vec4 right = textureGather(ps0,coord + highp vec2(ViewportInfo[0].x, 0.0), OperationMode);
128+
vec4 upDown;
129+
upDown.xy = textureGather(ps0,coord + highp vec2(0.0, -ViewportInfo[0].y),OperationMode).wz;
130+
upDown.zw = textureGather(ps0,coord+ highp vec2(0.0, ViewportInfo[0].y), OperationMode).yx;
131+
132+
float mean = (left.y+left.z+right.x+right.w)*0.25;
133+
left = left - vec4(mean);
134+
right = right - vec4(mean);
135+
upDown = upDown - vec4(mean);
136+
color.w =color[OperationMode] - mean;
137+
138+
float sum = (((((abs(left.x)+abs(left.y))+abs(left.z))+abs(left.w))+(((abs(right.x)+abs(right.y))+abs(right.z))+abs(right.w)))+(((abs(upDown.x)+abs(upDown.y))+abs(upDown.z))+abs(upDown.w)));
139+
float sumMean = 1.014185e+01/sum;
140+
float std = (sumMean*sumMean);
141+
142+
#if defined(UseEdgeDirection)
143+
vec3 data = vec3(std, edgeDirection(left, right));
144+
#else
145+
float data = std;
146+
#endif
147+
vec2 aWY = weightY(pl.x, pl.y+1.0, upDown.x,data);
148+
aWY += weightY(pl.x-1.0, pl.y+1.0, upDown.y,data);
149+
aWY += weightY(pl.x-1.0, pl.y-2.0, upDown.z,data);
150+
aWY += weightY(pl.x, pl.y-2.0, upDown.w,data);
151+
aWY += weightY(pl.x+1.0, pl.y-1.0, left.x,data);
152+
aWY += weightY(pl.x, pl.y-1.0, left.y,data);
153+
aWY += weightY(pl.x, pl.y, left.z,data);
154+
aWY += weightY(pl.x+1.0, pl.y, left.w,data);
155+
aWY += weightY(pl.x-1.0, pl.y-1.0, right.x,data);
156+
aWY += weightY(pl.x-2.0, pl.y-1.0, right.y,data);
157+
aWY += weightY(pl.x-2.0, pl.y, right.z,data);
158+
aWY += weightY(pl.x-1.0, pl.y, right.w,data);
159+
160+
float finalY = aWY.y/aWY.x;
161+
float maxY = max(max(left.y,left.z),max(right.x,right.w));
162+
float minY = min(min(left.y,left.z),min(right.x,right.w));
163+
float deltaY = clamp(EdgeSharpness*finalY, minY, maxY) -color.w;
164+
165+
//smooth high contrast input
166+
deltaY = clamp(deltaY, -23.0 / 255.0, 23.0 / 255.0);
167+
168+
color.x = clamp((color.x+deltaY),0.0,1.0);
169+
color.y = clamp((color.y+deltaY),0.0,1.0);
170+
color.z = clamp((color.z+deltaY),0.0,1.0);
171+
}
172+
}
173+
174+
color.w = 1.0; //assume alpha channel is not used
175+
out_Target0.xyzw = color;
176+
}

0 commit comments

Comments
 (0)