1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVFILTER_VSRC_GFXCAPTURE_SHADER_H
#define AVFILTER_VSRC_GFXCAPTURE_SHADER_H
#define HLSL_SHADER(shader) #shader
static const char render_shader_src[] = HLSL_SHADER(
struct VSOut {
float4 pos : SV_Position;
float2 uv : TEXCOORD0;
};
cbuffer cb : register(b0) {
float2 tS;
float2 dS;
float2 uvMin;
float2 uvMax;
uint to_unpremult;
uint to_srgb;
uint2 pad;
};
Texture2D t0 : register(t0);
SamplerState s0 : register(s0);
VSOut main_vs(uint id : SV_VertexID) {
VSOut o;
o.pos = float4(id == 2 ? 3.0 : -1.0, id == 1 ? 3.0 : -1.0, 0, 1);
o.uv = lerp(uvMin, uvMax, float2((o.pos.x + 1) * 0.5, 1 - (o.pos.y + 1) * 0.5));
return o;
}
float4 cubic(float v) {
float4 n = float4(1.0, 2.0, 3.0, 4.0) - v;
float4 s = n * n * n;
float x = s.x;
float y = s.y - 4.0 * s.x;
float z = s.z - 4.0 * s.y + 6.0 * s.x;
float w = 6.0 - x - y - z;
return float4(x, y, z, w) * (1.0 / 6.0);
}
float4 texBicubic(Texture2D t, SamplerState ss, float2 uv) {
float2 itS = 1.0 / tS;
float2 tc = uv * tS - 0.5;
float2 fxy = frac(tc);
tc -= fxy;
float4 xc = cubic(fxy.x);
float4 yc = cubic(fxy.y);
float4 s = float4(xc.xz + xc.yw, yc.xz + yc.yw);
float4 o = tc.xxyy + (float2(-0.5, 1.5)).xyxy + float4(xc.yw, yc.yw) / s;
o *= itS.xxyy;
float4 s0 = t.Sample(ss, o.xz);
float4 s1 = t.Sample(ss, o.yz);
float4 s2 = t.Sample(ss, o.xw);
float4 s3 = t.Sample(ss, o.yw);
float sx = s.x / (s.x + s.y);
float sy = s.z / (s.z + s.w);
return lerp(lerp(s3, s2, sx), lerp(s1, s0, sx), sy);
}
float4 unpremultiply(float4 c) {
if (c.a < 1e-6)
return float4(0.0, 0.0, 0.0, 0.0);
return float4(c.rgb / c.a, c.a);
}
float4 premultiply(float4 c) {
return float4(c.rgb * c.a, c.a);
}
float3 linear_to_srgb(float3 c) {
c = max(c, 0.0);
float3 lo = 12.92 * c;
float3 hi = 1.055 * pow(c, 1.0 / 2.4) - 0.055;
return saturate(lerp(hi, lo, step(c, 0.0031308)));
}
float4 fix_color(float4 c) {
if (to_unpremult || to_srgb)
c = unpremultiply(c);
if (to_srgb) {
c.rgb = linear_to_srgb(c.rgb);
if (!to_unpremult)
c = premultiply(c);
}
return c;
}
float4 main_ps(VSOut i) : SV_Target {
return fix_color(t0.Sample(s0, i.uv));
}
float4 main_ps_bicubic(VSOut i) : SV_Target {
if (all(tS == dS))
return main_ps(i);
return fix_color(texBicubic(t0, s0, i.uv));
}
);
#undef HLSL_SHADER
#endif /* AVFILTER_VSRC_GFXCAPTURE_SHADER_H */
|