[cosmetics] update date in GPL header
[vuplus_xbmc] / system / shaders / convolutionsep-6x6_d3d.fx
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 texture g_Texture;
23 texture g_KernelTexture;
24 texture g_IntermediateTexture;
25 float2  g_StepXY_P0;
26 float2  g_StepXY_P1;
27
28 sampler RGBSampler =
29   sampler_state {
30     Texture = <g_Texture>;
31     AddressU = CLAMP;
32     AddressV = CLAMP;
33     MipFilter = LINEAR;
34     MinFilter = POINT;
35     MagFilter = POINT;
36   };
37
38 sampler KernelSampler =
39   sampler_state
40   {
41     Texture = <g_KernelTexture>;
42     AddressU = CLAMP;
43     AddressV = CLAMP;
44     MipFilter = LINEAR;
45     MinFilter = LINEAR;
46     MagFilter = LINEAR;
47   };
48
49 sampler IntermediateSampler =
50   sampler_state {
51     Texture = <g_IntermediateTexture>;
52     AddressU = CLAMP;
53     AddressV = CLAMP;
54     MipFilter = LINEAR;
55     MinFilter = POINT;
56     MagFilter = POINT;
57   };
58
59 struct VS_OUTPUT
60 {
61   float4 Position   : POSITION;
62   float2 TextureUV  : TEXCOORD0;
63 };
64
65 struct PS_OUTPUT
66 {
67   float4 RGBColor : COLOR0;
68 };
69
70 half3 weight(float pos)
71 {
72   half3 w;
73 #ifdef HAS_RGBA
74   w = tex1D(KernelSampler, pos).rgb;
75 #else
76   w = tex1D(KernelSampler, pos).bgr;
77 #endif
78
79 #ifdef HAS_FLOAT_TEXTURE
80   return w;
81 #else
82   return w * 2.0 - 1.0;
83 #endif
84 }
85
86 half3 pixel(sampler samp, float xpos, float ypos)
87 {
88   return tex2D(samp, float2(xpos, ypos)).rgb;
89 }
90
91 // Code for first pass - horizontal
92
93 half3 getLine(float ypos, float3 xpos1, float3 xpos2, half3 linetaps1, half3 linetaps2)
94 {
95   return
96     pixel(RGBSampler, xpos1.r, ypos) * linetaps1.r +
97     pixel(RGBSampler, xpos1.g, ypos) * linetaps2.r +
98     pixel(RGBSampler, xpos1.b, ypos) * linetaps1.g +
99     pixel(RGBSampler, xpos2.r, ypos) * linetaps2.g +
100     pixel(RGBSampler, xpos2.g, ypos) * linetaps1.b +
101     pixel(RGBSampler, xpos2.b, ypos) * linetaps2.b;
102 }
103
104 PS_OUTPUT CONVOLUTION6x6Horiz(VS_OUTPUT In)
105 {
106   PS_OUTPUT OUT;
107
108   float2 pos = In.TextureUV + g_StepXY_P0 * 0.5;
109   float2 f = frac(pos / g_StepXY_P0);
110
111   half3 linetaps1 = weight((1.0 - f.x) / 2.0);
112   half3 linetaps2 = weight((1.0 - f.x) / 2.0 + 0.5);
113
114   // kernel generation code made sure taps add up to 1, no need to adjust here.
115
116   float2 xystart;
117   xystart.x = (-2.0 - f.x) * g_StepXY_P0.x + In.TextureUV.x;
118   xystart.y = In.TextureUV.y;
119
120   float3 xpos1 = float3(
121       xystart.x,
122       xystart.x + g_StepXY_P0.x,
123       xystart.x + g_StepXY_P0.x * 2.0);
124   float3 xpos2 = half3(
125       xystart.x + g_StepXY_P0.x * 3.0,
126       xystart.x + g_StepXY_P0.x * 4.0,
127       xystart.x + g_StepXY_P0.x * 5.0);
128
129   OUT.RGBColor.rgb = getLine(xystart.y, xpos1, xpos2, linetaps1, linetaps2);
130   OUT.RGBColor.a = 1.0;
131
132   return OUT;
133 }
134
135 // Code for second pass - vertical
136
137 half3 getRow(float xpos, float3 ypos1, float3 ypos2, half3 columntaps1, half3 columntaps2)
138 {
139   return
140     pixel(IntermediateSampler, xpos, ypos1.r) * columntaps1.r +
141     pixel(IntermediateSampler, xpos, ypos1.g) * columntaps2.r +
142     pixel(IntermediateSampler, xpos, ypos1.b) * columntaps1.g +
143     pixel(IntermediateSampler, xpos, ypos2.r) * columntaps2.g +
144     pixel(IntermediateSampler, xpos, ypos2.g) * columntaps1.b +
145     pixel(IntermediateSampler, xpos, ypos2.b) * columntaps2.b;
146 }
147
148 PS_OUTPUT CONVOLUTION6x6Vert(VS_OUTPUT In)
149 {
150   PS_OUTPUT OUT;
151
152   float2 pos = In.TextureUV + g_StepXY_P1 * 0.5;
153   float2 f = frac(pos / g_StepXY_P1);
154
155   half3 columntaps1 = weight((1.0 - f.y) / 2.0);
156   half3 columntaps2 = weight((1.0 - f.y) / 2.0 + 0.5);
157
158   // kernel generation code made sure taps add up to 1, no need to adjust here.
159
160   float2 xystart;
161   xystart.x = In.TextureUV.x;
162   xystart.y = (-2.0 - f.y) * g_StepXY_P1.y + In.TextureUV.y;
163
164   float3 ypos1 = float3(
165       xystart.y,
166       xystart.y + g_StepXY_P1.y,
167       xystart.y + g_StepXY_P1.y * 2.0);
168   float3 ypos2 = half3(
169       xystart.y + g_StepXY_P1.y * 3.0,
170       xystart.y + g_StepXY_P1.y * 4.0,
171       xystart.y + g_StepXY_P1.y * 5.0);
172
173   OUT.RGBColor.rgb = getRow(xystart.x, ypos1, ypos2, columntaps1, columntaps2);
174   OUT.RGBColor.a = 1.0;
175
176   return OUT;
177 }
178
179 technique SCALER_T
180 {
181   pass P0
182   {
183     PixelShader  = compile ps_3_0 CONVOLUTION6x6Horiz();
184     ZEnable = False;
185     FillMode = Solid;
186     FogEnable = False;
187   }
188   pass P1
189   {
190     PixelShader  = compile ps_3_0 CONVOLUTION6x6Vert();
191     ZEnable = False;
192     FillMode = Solid;
193     FogEnable = False;
194   }
195 };