PageRenderTime 21ms CodeModel.GetById 13ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/system/shaders/yuv2rgb_d3d.fx

http://github.com/xbmc/xbmc
Unknown | 136 lines | 123 code | 13 blank | 0 comment | 0 complexity | 5153e6f35d53886dd83692710bdcfcfe MD5 | raw file
  1/*
  2 *      Copyright (C) 2005-2013 Team XBMC
  3 *      http://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, see
 17 *  <http://www.gnu.org/licenses/>.
 18 *
 19 */
 20
 21texture2D  g_Texture[3];
 22float4x4   g_ColorMatrix;
 23float2     g_StepXY;
 24float2     g_viewPort;
 25
 26
 27SamplerState YUVSampler : IMMUTABLE
 28{
 29  AddressU = CLAMP;
 30  AddressV = CLAMP;
 31  Filter   = MIN_MAG_MIP_LINEAR;
 32};
 33#ifdef NV12_SNORM_UV
 34SamplerState UVSamplerSNORM : IMMUTABLE
 35{
 36  AddressU = CLAMP;
 37  AddressV = CLAMP;
 38  Filter   = MIN_MAG_MIP_POINT;
 39};
 40#endif
 41
 42struct VS_INPUT
 43{
 44  float4 Position   : POSITION;
 45  float2 TextureY   : TEXCOORD0;
 46  float2 TextureUV  : TEXCOORD1;
 47};
 48
 49struct VS_OUTPUT
 50{
 51  float2 TextureY   : TEXCOORD0;
 52  float2 TextureUV  : TEXCOORD1;
 53  float4 Position   : SV_POSITION;
 54};
 55
 56VS_OUTPUT VS(VS_INPUT In)
 57{
 58  VS_OUTPUT output = (VS_OUTPUT)0;
 59  output.Position.x =  (In.Position.x / (g_viewPort.x  / 2.0)) - 1;
 60  output.Position.y = -(In.Position.y / (g_viewPort.y / 2.0)) + 1;
 61  output.Position.z = output.Position.z;
 62  output.Position.w = 1.0;
 63  output.TextureY   = In.TextureY;
 64  output.TextureUV  = In.TextureUV;
 65
 66  return output;
 67}
 68
 69#ifdef NV12_SNORM_UV
 70inline float unormU(float c)
 71{
 72  c *= 0.5;
 73  if (c < 0.0) c += 1.0;
 74  return saturate(c);
 75}
 76inline float2 unormUV(float2 rg)
 77{
 78  return float2(unormU(rg.x), unormU(rg.y));
 79}
 80#endif
 81
 82float4 YUV2RGB(VS_OUTPUT In) : SV_TARGET
 83{
 84#if defined(XBMC_YV12) //|| defined(XBMC_NV12)
 85  float4 YUV = float4(g_Texture[0].Sample(YUVSampler, In.TextureY ).r
 86                    , g_Texture[1].Sample(YUVSampler, In.TextureUV).r
 87                    , g_Texture[2].Sample(YUVSampler, In.TextureUV).r
 88                    , 1.0);
 89#elif defined(XBMC_NV12)
 90  float4 YUV = float4(g_Texture[0].Sample(YUVSampler, In.TextureY).r
 91  #if defined(NV12_SNORM_UV)
 92                    , unormUV(g_Texture[1].Sample(UVSamplerSNORM, In.TextureUV).rg)
 93  #else
 94                    , g_Texture[1].Sample(YUVSampler, In.TextureUV).rg
 95  #endif
 96                    , 1.0);
 97#elif defined(XBMC_YUY2) || defined(XBMC_UYVY)
 98  // The HLSL compiler is smart enough to optimize away these redundant assignments.
 99  // That way the code is almost identical to the OGL shader.
100  float2 stepxy = g_StepXY;
101  float2 pos    = In.TextureY;
102  pos           = float2(pos.x - (stepxy.x * 0.25), pos.y);
103  float2 f      = frac(pos / stepxy);
104
105  //y axis will be correctly interpolated by opengl
106  //x axis will not, so we grab two pixels at the center of two columns and interpolate ourselves
107  float4 c1 = g_Texture[0].Sample(YUVSampler, float2(pos.x + ((0.5 - f.x) * stepxy.x), pos.y));
108  float4 c2 = g_Texture[0].Sample(YUVSampler, float2(pos.x + ((1.5 - f.x) * stepxy.x), pos.y));
109
110  /* each pixel has two Y subpixels and one UV subpixel
111      YUV  Y  YUV
112      check if we're left or right of the middle Y subpixel and interpolate accordingly*/
113  #if defined(XBMC_YUY2) // BGRA = YUYV
114    float  leftY  = lerp(c1.b, c1.r, f.x * 2.0);
115    float  rightY = lerp(c1.r, c2.b, f.x * 2.0 - 1.0);
116    float2 outUV  = lerp(c1.ga, c2.ga, f.x);
117  #elif defined(XBMC_UYVY) // BGRA = UYVY
118    float  leftY  = lerp(c1.g, c1.a, f.x * 2.0);
119    float  rightY = lerp(c1.a, c2.g, f.x * 2.0 - 1.0);
120    float2 outUV  = lerp(c1.br, c2.br, f.x);
121  #endif
122    float  outY   = lerp(leftY, rightY, step(0.5, f.x));
123    float4 YUV    = float4(outY, outUV, 1.0);
124#endif
125
126  return mul(YUV, g_ColorMatrix);
127}
128
129technique11 YUV2RGB_T
130{
131  pass P0
132  {
133    SetVertexShader( CompileShader( vs_4_0_level_9_1, VS() ) );
134    SetPixelShader( CompileShader( ps_4_0_level_9_1, YUV2RGB() ) );
135  }
136};