[WinRenderer] Re-work color shader. try to fix wrong colors on some hardware.
authorAnton Fedchin <afedchin@ruswizards.com>
Sun, 6 Mar 2016 20:15:27 +0000 (23:15 +0300)
committerAnton Fedchin <afedchin@ruswizards.com>
Sun, 20 Mar 2016 17:09:36 +0000 (20:09 +0300)
system/shaders/yuv2rgb_d3d.fx
xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp
xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h
xbmc/guilib/D3DResource.cpp
xbmc/guilib/D3DResource.h

index 6fb9cf3..221de95 100644 (file)
@@ -18,9 +18,7 @@
  *
  */
 
-texture2D  g_YTexture;
-texture2D  g_UTexture;
-texture2D  g_VTexture;
+texture2D  g_Texture[3];
 float4x4   g_ColorMatrix;
 float2     g_StepXY;
 float2     g_viewPort;
@@ -45,15 +43,13 @@ struct VS_INPUT
 {
   float4 Position   : POSITION;
   float2 TextureY   : TEXCOORD0;
-  float2 TextureU   : TEXCOORD1;
-  float2 TextureV   : TEXCOORD2;
+  float2 TextureUV  : TEXCOORD1;
 };
 
 struct VS_OUTPUT
 {
   float2 TextureY   : TEXCOORD0;
-  float2 TextureU   : TEXCOORD1;
-  float2 TextureV   : TEXCOORD2;
+  float2 TextureUV  : TEXCOORD1;
   float4 Position   : SV_POSITION;
 };
 
@@ -65,8 +61,7 @@ VS_OUTPUT VS(VS_INPUT In)
   output.Position.z = output.Position.z;
   output.Position.w = 1.0;
   output.TextureY   = In.TextureY;
-  output.TextureU   = In.TextureU;
-  output.TextureV   = In.TextureV;
+  output.TextureUV  = In.TextureUV;
 
   return output;
 }
@@ -87,16 +82,16 @@ inline float2 unormUV(float2 rg)
 float4 YUV2RGB(VS_OUTPUT In) : SV_TARGET
 {
 #if defined(XBMC_YV12) //|| defined(XBMC_NV12)
-  float4 YUV = float4(g_YTexture.Sample(YUVSampler, In.TextureY).r
-                    , g_UTexture.Sample(YUVSampler, In.TextureU).r
-                    , g_VTexture.Sample(YUVSampler, In.TextureV).r
+  float4 YUV = float4(g_Texture[0].Sample(YUVSampler, In.TextureY ).r
+                    , g_Texture[1].Sample(YUVSampler, In.TextureUV).r
+                    , g_Texture[2].Sample(YUVSampler, In.TextureUV).r
                     , 1.0);
 #elif defined(XBMC_NV12)
-  float4 YUV = float4(g_YTexture.Sample(YUVSampler, In.TextureY).r
+  float4 YUV = float4(g_Texture[0].Sample(YUVSampler, In.TextureY).r
   #if defined(NV12_SNORM_UV)
-                    , unormUV(g_UTexture.Sample(UVSamplerSNORM, In.TextureU).rg)
+                    , unormUV(g_Texture[1].Sample(UVSamplerSNORM, In.TextureUV).rg)
   #else
-                    , g_UTexture.Sample(YUVSampler, In.TextureU).rg
+                    , g_Texture[1].Sample(YUVSampler, In.TextureUV).rg
   #endif
                     , 1.0);
 #elif defined(XBMC_YUY2) || defined(XBMC_UYVY)
@@ -109,8 +104,8 @@ float4 YUV2RGB(VS_OUTPUT In) : SV_TARGET
 
   //y axis will be correctly interpolated by opengl
   //x axis will not, so we grab two pixels at the center of two columns and interpolate ourselves
-  float4 c1 = g_YTexture.Sample(YUVSampler, float2(pos.x + ((0.5 - f.x) * stepxy.x), pos.y));
-  float4 c2 = g_YTexture.Sample(YUVSampler, float2(pos.x + ((1.5 - f.x) * stepxy.x), pos.y));
+  float4 c1 = g_Texture[0].Sample(YUVSampler, float2(pos.x + ((0.5 - f.x) * stepxy.x), pos.y));
+  float4 c2 = g_Texture[0].Sample(YUVSampler, float2(pos.x + ((1.5 - f.x) * stepxy.x), pos.y));
 
   /* each pixel has two Y subpixels and one UV subpixel
       YUV  Y  YUV
@@ -128,7 +123,7 @@ float4 YUV2RGB(VS_OUTPUT In) : SV_TARGET
     float4 YUV    = float4(outY, outUV, 1.0);
 #endif
 
-  return float4(mul(YUV, g_ColorMatrix).rgb, 1.0);
+  return mul(YUV, g_ColorMatrix);
 }
 
 technique11 YUV2RGB_T
index 3bf9bd5..a90412d 100644 (file)
@@ -300,7 +300,6 @@ bool CYUV2RGBShader::Create(unsigned int sourceWidth, unsigned int sourceHeight,
     { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
     { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,    0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
     { "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT,    0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
-    { "TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT,    0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
   };
 
   if (!CWinShader::CreateInputLayout(layout, ARRAYSIZE(layout)))
@@ -349,32 +348,32 @@ void CYUV2RGBShader::PrepareParameters(CRect sourceRect,
     v[0].z = 0.0f;
     v[0].tu = sourceRect.x1 / m_sourceWidth;
     v[0].tv = sourceRect.y1 / m_sourceHeight;
-    v[0].tu2 = v[0].tu3 = (sourceRect.x1 / 2.0f) / (m_sourceWidth>>1);
-    v[0].tv2 = v[0].tv3 = (sourceRect.y1 / 2.0f) / (m_sourceHeight>>1);
+    v[0].tu2 = (sourceRect.x1 / 2.0f) / (m_sourceWidth>>1);
+    v[0].tv2 = (sourceRect.y1 / 2.0f) / (m_sourceHeight>>1);
 
     v[1].x = m_dest[1].x;
     v[1].y = m_dest[1].y;
     v[1].z = 0.0f;
     v[1].tu = sourceRect.x2 / m_sourceWidth;
     v[1].tv = sourceRect.y1 / m_sourceHeight;
-    v[1].tu2 = v[1].tu3 = (sourceRect.x2 / 2.0f) / (m_sourceWidth>>1);
-    v[1].tv2 = v[1].tv3 = (sourceRect.y1 / 2.0f) / (m_sourceHeight>>1);
+    v[1].tu2 = (sourceRect.x2 / 2.0f) / (m_sourceWidth>>1);
+    v[1].tv2 = (sourceRect.y1 / 2.0f) / (m_sourceHeight>>1);
 
     v[2].x = m_dest[2].x;
     v[2].y = m_dest[2].y;
     v[2].z = 0.0f;
     v[2].tu = sourceRect.x2 / m_sourceWidth;
     v[2].tv = sourceRect.y2 / m_sourceHeight;
-    v[2].tu2 = v[2].tu3 = (sourceRect.x2 / 2.0f) / (m_sourceWidth>>1);
-    v[2].tv2 = v[2].tv3 = (sourceRect.y2 / 2.0f) / (m_sourceHeight>>1);
+    v[2].tu2 = (sourceRect.x2 / 2.0f) / (m_sourceWidth>>1);
+    v[2].tv2 = (sourceRect.y2 / 2.0f) / (m_sourceHeight>>1);
 
     v[3].x = m_dest[3].x;
     v[3].y = m_dest[3].y;
     v[3].z = 0.0f;
     v[3].tu = sourceRect.x1 / m_sourceWidth;
     v[3].tv = sourceRect.y2 / m_sourceHeight;
-    v[3].tu2 = v[3].tu3 = (sourceRect.x1 / 2.0f) / (m_sourceWidth>>1);
-    v[3].tv2 = v[3].tv3 = (sourceRect.y2 / 2.0f) / (m_sourceHeight>>1);
+    v[3].tu2 = (sourceRect.x1 / 2.0f) / (m_sourceWidth>>1);
+    v[3].tv2 = (sourceRect.y2 / 2.0f) / (m_sourceHeight>>1);
 
     CWinShader::UnlockVertexBuffer();
   }
@@ -388,12 +387,15 @@ void CYUV2RGBShader::PrepareParameters(CRect sourceRect,
 void CYUV2RGBShader::SetShaderParameters(YUVBuffer* YUVbuf)
 {
   m_effect.SetTechnique("YUV2RGB_T");
+  SVideoPlane *planes = YUVbuf->planes;
+  ID3D11ShaderResourceView* ppSRView[3] =
+  {
+    planes[0].texture.GetShaderResource(),
+    planes[1].texture.GetShaderResource(),
+    planes[2].texture.GetShaderResource(),
+  };
+  m_effect.SetResources("g_Texture", ppSRView, YUVbuf->GetActivePlanes());
   m_effect.SetMatrix("g_ColorMatrix", m_matrix.Matrix());
-  m_effect.SetTexture("g_YTexture", YUVbuf->planes[0].texture);
-  if (YUVbuf->GetActivePlanes() > 1)
-    m_effect.SetTexture("g_UTexture", YUVbuf->planes[1].texture);
-  if (YUVbuf->GetActivePlanes() > 2)
-    m_effect.SetTexture("g_VTexture", YUVbuf->planes[2].texture);
   m_effect.SetFloatArray("g_StepXY", m_texSteps, ARRAY_SIZE(m_texSteps));
 
   UINT numPorts = 1;
index 41aed5f..a12fdf0 100644 (file)
@@ -111,8 +111,7 @@ private:
   struct CUSTOMVERTEX {
       FLOAT x, y, z;
       FLOAT tu, tv;   // Y Texture coordinates
-      FLOAT tu2, tv2; // U Texture coordinates
-      FLOAT tu3, tv3; // V Texture coordinates
+      FLOAT tu2, tv2; // U and V Textures coordinates
   };
 };
 
index 8aa8125..36aa6a8 100644 (file)
@@ -561,6 +561,17 @@ bool CD3DEffect::SetTexture(LPCSTR handle, CD3DTexture &texture)
   return false;
 }
 
+bool CD3DEffect::SetResources(LPCSTR handle, ID3D11ShaderResourceView** ppSRViews, size_t count)
+{
+  if (m_effect)
+  {
+    ID3DX11EffectShaderResourceVariable* var = m_effect->GetVariableByName(handle)->AsShaderResource();
+    if (var->IsValid())
+      return SUCCEEDED(var->SetResourceArray(ppSRViews, 0, count));
+  }
+  return false;
+}
+
 bool CD3DEffect::SetConstantBuffer(LPCSTR handle, ID3D11Buffer *buffer)
 {
   if (m_effect)
index ed6cf96..dc2b2ba 100644 (file)
@@ -180,6 +180,7 @@ public:
   bool SetMatrix(LPCSTR handle, const XMFLOAT4X4* mat);
   bool SetTechnique(LPCSTR handle);
   bool SetTexture(LPCSTR handle, CD3DTexture &texture);
+  bool SetResources(LPCSTR handle, ID3D11ShaderResourceView** ppSRViews, size_t count);
   bool SetConstantBuffer(LPCSTR handle, ID3D11Buffer *buffer);
   bool SetScalar(LPCSTR handle, float value);
   bool Begin(UINT *passes, DWORD flags);