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