2 * Copyright (C) 2005-2013 Team XBMC
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)
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.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "output_d3d.fx"
23 texture2D g_Texture[3];
24 float4x4 g_ColorMatrix;
31 SamplerState YUVSampler : IMMUTABLE
35 Filter = MIN_MAG_MIP_LINEAR;
40 float4 Position : POSITION;
41 float2 TextureY : TEXCOORD0;
42 float2 TextureUV : TEXCOORD1;
47 float2 TextureY : TEXCOORD0;
48 float2 TextureUV : TEXCOORD1;
49 float4 Position : SV_POSITION;
52 VS_OUTPUT VS(VS_INPUT In)
54 VS_OUTPUT output = (VS_OUTPUT)0;
55 output.Position.x = (In.Position.x / (g_viewPort.x / 2.0)) - 1;
56 output.Position.y = -(In.Position.y / (g_viewPort.y / 2.0)) + 1;
57 output.Position.z = output.Position.z;
58 output.Position.w = 1.0;
59 output.TextureY = In.TextureY;
60 output.TextureUV = In.TextureUV;
66 inline float unormU(float c)
69 if (c < 0.0) c += 1.0;
72 inline float2 unormUV(float2 rg)
74 return float2(unormU(rg.x), unormU(rg.y));
78 float4 YUV2RGB(VS_OUTPUT In) : SV_TARGET
80 #if defined(XBMC_YV12) //|| defined(XBMC_NV12)
81 float4 YUV = float4(g_Texture[0].Sample(YUVSampler, In.TextureY ).r
82 , g_Texture[1].Sample(YUVSampler, In.TextureUV).r
83 , g_Texture[2].Sample(YUVSampler, In.TextureUV).r
85 #elif defined(XBMC_NV12)
86 float4 YUV = float4(g_Texture[0].Sample(YUVSampler, In.TextureY).r
87 #if defined(NV12_SNORM_UV)
88 , unormUV(g_Texture[1].Sample(YUVSampler, In.TextureUV).rg)
90 , g_Texture[1].Sample(YUVSampler, In.TextureUV).rg
93 #elif defined(XBMC_YUY2) || defined(XBMC_UYVY)
94 // The HLSL compiler is smart enough to optimize away these redundant assignments.
95 // That way the code is almost identical to the OGL shader.
96 float2 stepxy = g_StepXY;
97 float2 pos = In.TextureY;
98 pos = float2(pos.x - (stepxy.x * 0.25), pos.y);
99 float2 f = frac(pos / stepxy);
101 //y axis will be correctly interpolated by opengl
102 //x axis will not, so we grab two pixels at the center of two columns and interpolate ourselves
103 float4 c1 = g_Texture[0].Sample(YUVSampler, float2(pos.x + ((0.5 - f.x) * stepxy.x), pos.y));
104 float4 c2 = g_Texture[0].Sample(YUVSampler, float2(pos.x + ((1.5 - f.x) * stepxy.x), pos.y));
106 /* each pixel has two Y subpixels and one UV subpixel
108 check if we're left or right of the middle Y subpixel and interpolate accordingly*/
109 #if defined(XBMC_YUY2) // BGRA = YUYV
110 float leftY = lerp(c1.b, c1.r, f.x * 2.0);
111 float rightY = lerp(c1.r, c2.b, f.x * 2.0 - 1.0);
112 float2 outUV = lerp(c1.ga, c2.ga, f.x);
113 #elif defined(XBMC_UYVY) // BGRA = UYVY
114 float leftY = lerp(c1.g, c1.a, f.x * 2.0);
115 float rightY = lerp(c1.a, c2.g, f.x * 2.0 - 1.0);
116 float2 outUV = lerp(c1.br, c2.br, f.x);
118 float outY = lerp(leftY, rightY, step(0.5, f.x));
119 float4 YUV = float4(outY, outUV, 1.0);
122 float4 rgb = mul(YUV, g_ColorMatrix);
123 #if defined(XBMC_COL_CONVERSION)
124 rgb.rgb = pow(max(0.0, rgb.rgb), g_gammaSrc);
125 rgb.rgb = max(0.0, mul(rgb, g_primMat).rgb);
126 rgb.rgb = pow(rgb.rgb, g_gammaDstInv);
128 return output4(rgb, In.TextureY);
131 technique11 YUV2RGB_T
135 SetVertexShader( CompileShader( vs_4_0_level_9_1, VS() ) );
136 SetPixelShader( CompileShader( ps_4_0_level_9_1, YUV2RGB() ) );