[rendering] Rework to DirectX11.
authorAnton Fedchin <afedchin@ruswizards.com>
Wed, 22 Apr 2015 15:18:10 +0000 (18:18 +0300)
committerAnton Fedchin <afedchin@ruswizards.com>
Sat, 4 Jul 2015 07:25:11 +0000 (10:25 +0300)
xbmc/rendering/RenderSystem.h
xbmc/rendering/dx/GUIWindowTestPatternDX.cpp
xbmc/rendering/dx/GUIWindowTestPatternDX.h
xbmc/rendering/dx/RenderSystemDX.cpp
xbmc/rendering/dx/RenderSystemDX.h

index 9f1daf4..923f1ff 100644 (file)
@@ -76,6 +76,7 @@ enum RENDER_STEREO_MODE
   RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA,
   RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE,
   RENDER_STEREO_MODE_INTERLACED,
+  RENDER_STEREO_MODE_CHECKERBOARD,
   RENDER_STEREO_MODE_HARDWAREBASED,
   RENDER_STEREO_MODE_MONO,
   RENDER_STEREO_MODE_COUNT,
index 706e947..3ff800c 100644 (file)
   #define M_PI       3.14159265358979323846
 #endif
 
-#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
-
 CGUIWindowTestPatternDX::CGUIWindowTestPatternDX(void) : CGUIWindowTestPattern()
 {
+  m_vb = NULL;
+  m_bufferWidth = 0;
 }
 
 CGUIWindowTestPatternDX::~CGUIWindowTestPatternDX(void)
 {
+  SAFE_RELEASE(m_vb);
+  m_bufferWidth = 0;
 }
 
 void CGUIWindowTestPatternDX::DrawVerticalLines(int top, int left, int bottom, int right)
 {
-  CUSTOMVERTEX* vert = new CUSTOMVERTEX[2+(right-left)];
+  Vertex* vert = new Vertex[2 + (right - left)];
   int p = 0;
   for (int i = left; i <= right; i += 2)
   {
-    vert[p].x = (float)i;
-    vert[p].y = (float)top;
-    vert[p].z = 0.5f;
-    vert[p].rhw = 1.0f;
-    vert[p].color = D3DCOLOR_COLORVALUE(m_white, m_white, m_white, 1.0f);
+    vert[p].pos.x = (float)i;
+    vert[p].pos.y = (float)top;
+    vert[p].pos.z = 0.5f;
+    vert[p].color = XMFLOAT4(m_white, m_white, m_white, 1.0f);
     ++p;
-    vert[p].x = (float)i;
-    vert[p].y = (float)bottom;
-    vert[p].z = 0.5f;
-    vert[p].rhw = 1.0f;
-    vert[p].color = D3DCOLOR_COLORVALUE(m_white, m_white, m_white, 1.0f);
+    vert[p].pos.x = (float)i;
+    vert[p].pos.y = (float)bottom;
+    vert[p].pos.z = 0.5f;
+    vert[p].color = XMFLOAT4(m_white, m_white, m_white, 1.0f);
     ++p;
   }
-  g_Windowing.Get3DDevice()->SetFVF(D3DFVF_CUSTOMVERTEX);
-  g_Windowing.Get3DDevice()->DrawPrimitiveUP(D3DPT_LINELIST, p/2, vert, sizeof(CUSTOMVERTEX));
+  UpdateVertexBuffer(vert, p);
+
+  ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context();
+  CGUIShaderDX* pGUIShader = g_Windowing.GetGUIShader();
+
+  pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT);
+  unsigned stride = sizeof(Vertex), offset = 0;
+  pContext->IASetVertexBuffers(0, 1, &m_vb, &stride, &offset);
+  pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
+  pGUIShader->Draw(p, 0);
 
   delete [] vert;
 }
 
 void CGUIWindowTestPatternDX::DrawHorizontalLines(int top, int left, int bottom, int right)
 {
-  CUSTOMVERTEX* vert = new CUSTOMVERTEX[2+(bottom-top)];
+  Vertex* vert = new Vertex[2 + (bottom - top)];
   int p = 0;
   for (int i = top; i <= bottom; i += 2)
   {
-    vert[p].x = (float)left;
-    vert[p].y = (float)i;
-    vert[p].z = 0.5f;
-    vert[p].rhw = 1.0f;
-    vert[p].color = D3DCOLOR_COLORVALUE(m_white, m_white, m_white, 1.0f);
+    vert[p].pos.x = (float)left;
+    vert[p].pos.y = (float)i;
+    vert[p].pos.z = 0.5f;
+    vert[p].color = XMFLOAT4(m_white, m_white, m_white, 1.0f);
     ++p;
-    vert[p].x = (float)right;
-    vert[p].y = (float)i;
-    vert[p].z = 0.5f;
-    vert[p].rhw = 1.0f;
-    vert[p].color = D3DCOLOR_COLORVALUE(m_white, m_white, m_white, 1.0f);
+    vert[p].pos.x = (float)right;
+    vert[p].pos.y = (float)i;
+    vert[p].pos.z = 0.5f;
+    vert[p].color = XMFLOAT4(m_white, m_white, m_white, 1.0f);
     ++p;
   }
-  g_Windowing.Get3DDevice()->SetFVF(D3DFVF_CUSTOMVERTEX);
-  g_Windowing.Get3DDevice()->DrawPrimitiveUP(D3DPT_LINELIST, p/2, vert, sizeof(CUSTOMVERTEX));
+  UpdateVertexBuffer(vert, p);
+
+  ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context();
+  CGUIShaderDX* pGUIShader = g_Windowing.GetGUIShader();
+
+  pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT);
+  unsigned stride = sizeof(Vertex), offset = 0;
+  pContext->IASetVertexBuffers(0, 1, &m_vb, &stride, &offset);
+  pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
+  pGUIShader->Draw(p, 0);
 
   delete [] vert;
 }
@@ -91,7 +105,7 @@ void CGUIWindowTestPatternDX::DrawCheckers(int top, int left, int bottom, int ri
   int c = (bottom-top+1)*(1+(right-left)/2);
   if (c < 1)
     return;
-  CUSTOMVERTEX* vert = new CUSTOMVERTEX[c];
+  Vertex* vert = new Vertex[c];
   int i=0;
   for (int y = top; y <= bottom; y++)
   {
@@ -99,25 +113,31 @@ void CGUIWindowTestPatternDX::DrawCheckers(int top, int left, int bottom, int ri
     {
       if (y % 2 == 0)
       {
-        vert[i].x = (float)x;
-        vert[i].y = (float)y;
-        vert[i].z = 0.5f;
-        vert[i].rhw = 1.0f;
-        vert[i].color = D3DCOLOR_COLORVALUE(m_white, m_white, m_white, 1.0f);
+        vert[i].pos.x = (float)x;
+        vert[i].pos.y = (float)y;
+        vert[i].pos.z = 0.5f;
+        vert[i].color = XMFLOAT4(m_white, m_white, m_white, 1.0f);
       }
       else
       {
-        vert[i].x = (float)x+1.0f;
-        vert[i].y = (float)y;
-        vert[i].z = 0.5f;
-        vert[i].rhw = 1.0f;
-        vert[i].color = D3DCOLOR_COLORVALUE(m_white, m_white, m_white, 1.0f);
+        vert[i].pos.x = (float)x+1.0f;
+        vert[i].pos.y = (float)y;
+        vert[i].pos.z = 0.5f;
+        vert[i].color = XMFLOAT4(m_white, m_white, m_white, 1.0f);
       }
       ++i;
     }
   }
-  g_Windowing.Get3DDevice()->SetFVF(D3DFVF_CUSTOMVERTEX);
-  g_Windowing.Get3DDevice()->DrawPrimitiveUP(D3DPT_POINTLIST, i, vert, sizeof(CUSTOMVERTEX));
+  UpdateVertexBuffer(vert, i);
+
+  ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context();
+  CGUIShaderDX* pGUIShader = g_Windowing.GetGUIShader();
+
+  pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT);
+  unsigned stride = sizeof(Vertex), offset = 0;
+  pContext->IASetVertexBuffers(0, 1, &m_vb, &stride, &offset);
+  pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
+  pGUIShader->Draw(i, 0);
 
   delete [] vert;
 }
@@ -166,29 +186,41 @@ void CGUIWindowTestPatternDX::DrawContrastBrightnessPattern(int top, int left, i
   DrawRectangle(x50p, (float)top, (float)right, y50p, color_white);
   DrawRectangle((float)left, (float)y50p, x50p, (float)bottom, color_white);
 
+  XMFLOAT4 xcolor_white, xcolor_black;
+  CD3DHelper::XMStoreColor(&xcolor_white, color_white);
+  CD3DHelper::XMStoreColor(&xcolor_black, color_black);
+
   // draw border lines
-  CUSTOMVERTEX vert[] = 
+  Vertex vert[] = 
   {
-    {(float)left, y5p, 0.5f, 1.0f, color_white},
-    {x50p, y5p, 0.5f, 1.0f, color_white},
-    {x5p, (float)top, 0.5f, 1.0f, color_white},
-    {x5p, y50p, 0.5f, 1.0f, color_white},
-    {x50p, y95p, 0.5f, 1.0f, color_white},
-    {(float)right, y95p, 0.5f, 1.0f, color_white},
-    {x95p, y50p, 0.5f, 1.0f, color_white},
-    {x95p, (float)bottom, 0.5f, 1.0f, color_white},
-
-    {x50p, y5p, 0.5f, 1.0f, color_black},
-    {(float)right, y5p, 0.5f, 1.0f, color_black},
-    {x5p, y50p, 0.5f, 1.0f, color_black},
-    {x5p, (float)bottom, 0.5f, 1.0f, color_black},
-    {(float)left, y95p, 0.5f, 1.0f, color_black},
-    {x50p, y95p, 0.5f, 1.0f, color_black},
-    {x95p, (float)top, 0.5f, 1.0f, color_black},
-    {x95p, y50p, 0.5f, 1.0f, color_black}
+    { XMFLOAT3((float)left, y5p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x50p, y5p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x5p, (float)top, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x5p, y50p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x50p, y95p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3((float)right, y95p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x95p, y50p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x95p, (float)bottom, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+
+    { XMFLOAT3(x50p, y5p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3((float)right, y5p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x5p, y50p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x5p, (float)bottom, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3((float)left, y95p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x50p, y95p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x95p, (float)top, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x95p, y50p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
   };
-  g_Windowing.Get3DDevice()->SetFVF(D3DFVF_CUSTOMVERTEX);
-  g_Windowing.Get3DDevice()->DrawPrimitiveUP(D3DPT_LINELIST, 8, vert, sizeof(CUSTOMVERTEX));
+  UpdateVertexBuffer(vert, ARRAYSIZE(vert));
+
+  ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context();
+  CGUIShaderDX* pGUIShader = g_Windowing.GetGUIShader();
+
+  pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT);
+  unsigned stride = sizeof(Vertex), offset = 0;
+  pContext->IASetVertexBuffers(0, 1, &m_vb, &stride, &offset);
+  pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
+  pGUIShader->Draw(ARRAYSIZE(vert), 0);
 
   // draw inner rectangles
   DrawRectangle(x12p, y12p, x37p, y37p, color_white);
@@ -225,7 +257,7 @@ void CGUIWindowTestPatternDX::DrawCircleEx(float originX, float originY, float r
   float vectorY;
   float vectorY1 = originY;
   float vectorX1 = originX;
-  CUSTOMVERTEX vert[1083]; // 361*3
+  Vertex vert[1084]; // 361*3 + 1
   int p = 0;
 
   for (int i = 0; i <= 360; i++)
@@ -233,50 +265,107 @@ void CGUIWindowTestPatternDX::DrawCircleEx(float originX, float originY, float r
     angle = (float)(((double)i)/57.29577957795135);
     vectorX = originX + (radius*(float)sin((double)angle));
     vectorY = originY + (radius*(float)cos((double)angle));
-    vert[p].x = originX;
-    vert[p].y = originY;
-    vert[p].z = 0.5f;
-    vert[p].rhw = 1.0f;
-    vert[p].color = color;
+    vert[p].pos.x = originX;
+    vert[p].pos.y = originY;
+    vert[p].pos.z = 0.5f;
+    CD3DHelper::XMStoreColor(&vert[p].color, color);
     ++p;
-    vert[p].x = vectorX1;
-    vert[p].y = vectorY1;
-    vert[p].z = 0.5f;
-    vert[p].rhw = 1.0f;
-    vert[p].color = color;
+    vert[p].pos.x = vectorX1;
+    vert[p].pos.y = vectorY1;
+    vert[p].pos.z = 0.5f;
+    CD3DHelper::XMStoreColor(&vert[p].color, color);
     ++p;
-    vert[p].x = vectorX;
-    vert[p].y = vectorY;
-    vert[p].z = 0.5f;
-    vert[p].rhw = 1.0f;
-    vert[p].color = color;
+    vert[p].pos.x = vectorX;
+    vert[p].pos.y = vectorY;
+    vert[p].pos.z = 0.5f;
+    CD3DHelper::XMStoreColor(&vert[p].color, color);
     ++p;
     vectorY1 = vectorY;
     vectorX1 = vectorX;
   }
-  g_Windowing.Get3DDevice()->SetFVF(D3DFVF_CUSTOMVERTEX);
-  g_Windowing.Get3DDevice()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 361, vert, sizeof(CUSTOMVERTEX));
+  vert[1083] = vert[0];
+
+  UpdateVertexBuffer(vert, ARRAYSIZE(vert));
+
+  ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context();
+  CGUIShaderDX* pGUIShader = g_Windowing.GetGUIShader();
+
+  pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT);
+  unsigned stride = sizeof(Vertex), offset = 0;
+  pContext->IASetVertexBuffers(0, 1, &m_vb, &stride, &offset);
+  pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+  pGUIShader->Draw(ARRAYSIZE(vert), 0);
 }
 
 void CGUIWindowTestPatternDX::BeginRender()
 {
-  g_Windowing.Get3DDevice()->Clear(0, NULL, D3DCLEAR_TARGET, 0, 0, 0);
+  ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context();
+  ID3D11RenderTargetView* renderTarget;
+
+  pContext->OMGetRenderTargets(1, &renderTarget, NULL);
+  float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+  pContext->ClearRenderTargetView(renderTarget, color);
+  renderTarget->Release();
 }
 
 void CGUIWindowTestPatternDX::EndRender()
 {
+  g_Windowing.GetGUIShader()->RestoreBuffers();
 }
 
 void CGUIWindowTestPatternDX::DrawRectangle(float x, float y, float x2, float y2, DWORD color)
 {
-  CUSTOMVERTEX vert[] = 
+  XMFLOAT4 float4;
+  CD3DHelper::XMStoreColor(&float4, color);
+
+  Vertex vert[] = 
   {
-    {x, y, 0.5f, 1.0f, color},
-    {x2, y, 0.5f, 1.0f, color},
-    {x2, y2, 0.5f, 1.0f, color},
-    {x, y2, 0.5f, 1.0f, color},
-    {x, y, 0.5f, 1.0f, color},
+    { XMFLOAT3( x, y, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x2, y, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x2, y2, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x2, y2, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3(x, y2, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
+    { XMFLOAT3( x, y, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) },
   };
-  g_Windowing.Get3DDevice()->SetFVF(D3DFVF_CUSTOMVERTEX);
-  g_Windowing.Get3DDevice()->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 3, vert, sizeof(CUSTOMVERTEX));
+
+  UpdateVertexBuffer(vert, ARRAYSIZE(vert));
+
+  ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context();
+  CGUIShaderDX* pGUIShader = g_Windowing.GetGUIShader();
+
+  pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT);
+  unsigned stride = sizeof(Vertex), offset = 0;
+  pContext->IASetVertexBuffers(0, 1, &m_vb, &stride, &offset);
+  pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+  pGUIShader->Draw(ARRAYSIZE(vert), 0);
+}
+
+void CGUIWindowTestPatternDX::UpdateVertexBuffer(Vertex *vertecies, unsigned count)
+{
+  unsigned width = sizeof(Vertex) * count;
+
+  if (!m_vb || width > m_bufferWidth) // create new
+  {
+    SAFE_RELEASE(m_vb);
+
+    CD3D11_BUFFER_DESC desc(width, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
+    D3D11_SUBRESOURCE_DATA initData = {};
+    initData.pSysMem = vertecies;
+    initData.SysMemPitch = width;
+    if (SUCCEEDED(g_Windowing.Get3D11Device()->CreateBuffer(&desc, &initData, &m_vb)))
+    {
+      m_bufferWidth = width;
+    }
+    return;
+  }
+  else // update 
+  {
+    ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context();
+    D3D11_MAPPED_SUBRESOURCE res;
+    if (SUCCEEDED(pContext->Map(m_vb, 0, D3D11_MAP_WRITE_DISCARD, 0, &res)))
+    {
+      memcpy(res.pData, vertecies, sizeof(Vertex) * count);
+      pContext->Unmap(m_vb, 0);
+    }
+  }
 }
index 40035f1..a6f084f 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "settings/windows/GUIWindowTestPattern.h"
+#include "guilib/GUIShaderDX.h"
 
 class CGUIWindowTestPatternDX : public CGUIWindowTestPattern
 {
@@ -39,14 +40,12 @@ private:
   virtual void DrawCircle(int originX, int originY, int radius);
   virtual void BeginRender();
   virtual void EndRender();
-
-  struct CUSTOMVERTEX
-  {
-    FLOAT x, y, z, rhw; // The transformed position for the vertex
-    DWORD color;        // The vertex color
-  };
+  virtual void UpdateVertexBuffer(Vertex *vertecies, unsigned count);
 
   void DrawRectangle(float x, float y, float x2, float y2, DWORD color);
   void DrawCircleEx(float originX, float originY, float radius, DWORD color);
+
+  ID3D11Buffer*   m_vb;
+  unsigned        m_bufferWidth;
 };
 
index c727b44..d3186de 100644 (file)
 
 #ifdef HAS_DX
 
-#include "threads/SystemClock.h"
+#include <DirectXPackedVector.h>
+#include "Application.h"
 #include "RenderSystemDX.h"
-#include "utils/log.h"
-#include "utils/TimeUtils.h"
-#include "utils/MathUtils.h"
-#include "guilib/GUIWindowManager.h"
-#include "threads/SingleLock.h"
+#include "cores/VideoRenderers/RenderManager.h"
 #include "guilib/D3DResource.h"
+#include "guilib/GUIShaderDX.h"
+#include "guilib/GUIWindowManager.h"
 #include "settings/AdvancedSettings.h"
-#include "Application.h"
-#include "video/VideoReferenceClock.h"
-#include "cores/VideoRenderers/RenderManager.h"
-#if (D3DX_SDK_VERSION >= 42) //aug 2009 sdk and up use dxerr
-  #include <Dxerr.h>
-#else
-  #include <dxerr9.h>
-  #define DXGetErrorString(hr)      DXGetErrorString9(hr)
-  #define DXGetErrorDescription(hr) DXGetErrorDescription9(hr)
-#endif
+#include "threads/SingleLock.h"
+#include "utils/MathUtils.h"
+#include "utils/TimeUtils.h"
+#include "utils/log.h"
+#include "win32/WIN32Util.h"
+#include "win32/dxerr.h"
 
-using namespace std;
+#pragma comment(lib, "d3d11.lib")
+#pragma comment(lib, "dxgi.lib")
+#pragma comment(lib, "dxguid.lib")
 
-// Dynamic loading of Direct3DCreate9Ex to keep compatibility with 2000/XP.
-typedef HRESULT (WINAPI *LPDIRECT3DCREATE9EX)( UINT SDKVersion, IDirect3D9Ex **ppD3D);
-static LPDIRECT3DCREATE9EX g_Direct3DCreate9Ex;
-static HMODULE             g_D3D9ExHandle;
+#define RATIONAL_TO_FLOAT(rational) ((rational.Denominator != 0) ? (float)rational.Numerator / (float)rational.Denominator : 0.0)
 
-static bool LoadD3D9Ex()
-{
-  HMODULE hD3d9Dll =  GetModuleHandle("d3d9.dll");
-  if (!hD3d9Dll)
-    return false;
-  g_Direct3DCreate9Ex = (LPDIRECT3DCREATE9EX)GetProcAddress(hD3d9Dll, "Direct3DCreate9Ex" );
-  if(g_Direct3DCreate9Ex == NULL)
-    return false;
-  return true;
-}
+using namespace DirectX::PackedVector;
 
 CRenderSystemDX::CRenderSystemDX() : CRenderSystemBase()
 {
   m_enumRenderingSystem = RENDERING_SYSTEM_DIRECTX;
 
-  m_pD3D        = NULL;
-  m_pD3DDevice  = NULL;
-  m_devType     = D3DDEVTYPE_HAL;
-#if defined(DEBUG_PS) || defined (DEBUG_VS)
-    m_devType = D3DDEVTYPE_REF
-#endif
   m_hFocusWnd   = NULL;
   m_hDeviceWnd  = NULL;
   m_nBackBufferWidth  = 0;
@@ -76,17 +55,44 @@ CRenderSystemDX::CRenderSystemDX() : CRenderSystemBase()
   m_bFullScreenDevice = false;
   m_bVSync          = true;
   m_nDeviceStatus   = S_OK;
-  m_stateBlock      = NULL;
   m_inScene         = false;
   m_needNewDevice   = false;
-  m_adapter         = D3DADAPTER_DEFAULT;
+  m_resizeInProgress = false;
   m_screenHeight    = 0;
   m_systemFreq      = CurrentHostFrequency();
-  m_useD3D9Ex       = false;
-  m_defaultD3DUsage = 0;
-  m_defaultD3DPool  = D3DPOOL_MANAGED;
 
-  ZeroMemory(&m_D3DPP, sizeof(D3DPRESENT_PARAMETERS));
+  m_defaultD3DUsage = D3D11_USAGE_DEFAULT;
+
+  m_featureLevel = D3D_FEATURE_LEVEL_11_1;
+  m_driverType = D3D_DRIVER_TYPE_HARDWARE;
+  m_adapter = NULL;
+  m_adapterIndex = -1;
+  m_pOutput = NULL;
+  m_dxgiFactory = NULL;
+  m_pD3DDev = NULL;
+  m_pImdContext = NULL;
+  m_pContext = NULL;
+
+  m_pSwapChain = NULL;
+  m_pSwapChain1 = NULL;
+  m_pRenderTargetView = NULL;
+  m_depthStencilState = NULL;
+  m_depthStencilView = NULL;
+  m_BlendEnableState = NULL;
+  m_BlendDisableState = NULL;
+  m_BlendEnabled = false;
+  m_RSScissorDisable = NULL;
+  m_RSScissorEnable = NULL;
+  m_ScissorsEnabled = false;
+
+  m_pTextureRight = NULL;
+  m_pRenderTargetViewRight = NULL;
+  m_pShaderResourceViewRight = NULL;
+  m_pGUIShader = NULL;
+  m_bResizeRequred = false;
+  m_bHWStereoEnabled = false;
+  ZeroMemory(&m_cachedMode, sizeof(m_cachedMode));
+  ZeroMemory(&m_viewPort, sizeof(m_viewPort));
 }
 
 CRenderSystemDX::~CRenderSystemDX()
@@ -96,50 +102,18 @@ CRenderSystemDX::~CRenderSystemDX()
 bool CRenderSystemDX::InitRenderSystem()
 {
   m_bVSync = true;
+  
+  CLog::Log(LOGDEBUG, __FUNCTION__" - Initializing D3D11 Factory...");
 
-  m_useD3D9Ex = (g_advancedSettings.m_AllowD3D9Ex && LoadD3D9Ex());
-  m_pD3D = NULL;
-
-  if (m_useD3D9Ex)
-  {
-    CLog::Log(LOGDEBUG, __FUNCTION__" - trying D3D9Ex...");
-    if (FAILED(g_Direct3DCreate9Ex(D3D_SDK_VERSION, (IDirect3D9Ex**) &m_pD3D)))
-    {
-      CLog::Log(LOGDEBUG, __FUNCTION__" - D3D9Ex creation failure, falling back to D3D9");
-      m_useD3D9Ex = false;
-    }
-    else
-    {
-      D3DCAPS9 caps;
-      memset(&caps, 0, sizeof(caps));
-      m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, m_devType, &caps);
-      // Evaluate if the driver is WDDM - this detection method is not guaranteed 100%
-      if (!g_advancedSettings.m_ForceD3D9Ex && (!(caps.Caps2 & D3DCAPS2_CANSHARERESOURCE) || !(caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES)))
-      {
-        CLog::Log(LOGDEBUG, __FUNCTION__" - driver looks like XPDM or earlier, falling back to D3D9");
-        m_useD3D9Ex = false;
-        m_pD3D->Release();
-      }
-      else
-      {
-        CLog::Log(LOGDEBUG, __FUNCTION__" - using D3D9Ex");
-      }
-    }
-  }
-
-  if (!m_useD3D9Ex)
+  HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&m_dxgiFactory));
+  if (FAILED(hr)) 
   {
-    m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
-    if(m_pD3D == NULL)
-      return false;
+    CLog::Log(LOGERROR, __FUNCTION__" - D3D11 initialization failed.");
+    return false;
   }
-
+  
   UpdateMonitor();
-
-  if(CreateDevice()==false)
-    return false;
-
-  return true;
+  return CreateDevice();
 }
 
 void CRenderSystemDX::SetRenderParams(unsigned int width, unsigned int height, bool fullScreen, float refreshRate)
@@ -152,25 +126,58 @@ void CRenderSystemDX::SetRenderParams(unsigned int width, unsigned int height, b
 
 void CRenderSystemDX::SetMonitor(HMONITOR monitor)
 {
-  if (!m_pD3D)
+  if (!m_dxgiFactory)
+    return;
+
+  DXGI_OUTPUT_DESC outputDesc;
+  if (m_pOutput && SUCCEEDED(m_pOutput->GetDesc(&outputDesc)) && outputDesc.Monitor == monitor)
     return;
 
   // find the appropriate screen
-  for (unsigned int adapter = 0; adapter < m_pD3D->GetAdapterCount(); adapter++)
+  IDXGIAdapter1*  pAdapter;
+  for (unsigned i = 0; m_dxgiFactory->EnumAdapters1(i, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++i)
   {
-    HMONITOR hMonitor = m_pD3D->GetAdapterMonitor(adapter);
-    if (hMonitor == monitor && adapter != m_adapter)
+    IDXGIOutput* pOutput;
+    for (unsigned j = 0; pAdapter->EnumOutputs(j, &pOutput) != DXGI_ERROR_NOT_FOUND; ++j)
     {
-      m_adapter       = adapter;
-      m_needNewDevice = true;
-      break;
+      if (FAILED(pOutput->GetDesc(&outputDesc)))
+        break;
+
+      if (outputDesc.Monitor == monitor)
+      {
+        // update monitor info
+        SAFE_RELEASE(m_pOutput);
+        m_pOutput = pOutput;
+
+        CLog::Log(LOGDEBUG, __FUNCTION__" - Selected %S output. ", outputDesc.DeviceName);
+
+        // check if adapter is changed
+        if (m_adapterIndex != i)
+        {
+          pAdapter->GetDesc(&m_adapterDesc);
+
+          CLog::Log(LOGDEBUG, __FUNCTION__" - Selected %S adapter. ", m_adapterDesc.Description, outputDesc.DeviceName);
+
+          SAFE_RELEASE(m_adapter);
+          m_adapter = pAdapter;
+
+          m_needNewDevice = true;
+          m_adapterIndex = i;
+
+          return;
+        }
+
+        return;
+      }
+      pOutput->Release();
     }
+    pAdapter->Release();
   }
 }
 
 bool CRenderSystemDX::ResetRenderSystem(int width, int height, bool fullScreen, float refreshRate)
 {
-  if (!m_pD3DDevice)
+  if (!m_pD3DDev)
     return false;
 
   if (m_hDeviceWnd != NULL)
@@ -182,15 +189,17 @@ bool CRenderSystemDX::ResetRenderSystem(int width, int height, bool fullScreen,
 
   SetRenderParams(width, height, fullScreen, refreshRate);
 
-  CRect rc;
-  rc.SetRect(0, 0, (float)width, (float)height);
+  CRect rc(0, 0, float(width), float(height));
   SetViewPort(rc);
 
-  BuildPresentParameters();
-
-  if (m_useD3D9Ex && !m_needNewDevice)
-    m_nDeviceStatus = ((IDirect3DDevice9Ex*)m_pD3DDevice)->ResetEx(&m_D3DPP, m_D3DPP.Windowed ? NULL : &m_D3DDMEX);
-  else
+  if (!m_needNewDevice)
+  {
+    CreateWindowSizeDependentResources();
+    SetFullScreenInternal();
+    if (m_bResizeRequred)
+      CreateWindowSizeDependentResources();
+  }
+  else 
   {
     OnDeviceLost();
     OnDeviceReset();
@@ -204,120 +213,215 @@ void CRenderSystemDX::OnMove()
   if (!m_bRenderCreated)
     return;
 
-  HMONITOR currentMonitor = m_pD3D->GetAdapterMonitor(m_adapter);
+  DXGI_OUTPUT_DESC outputDesc;
+  m_pOutput->GetDesc(&outputDesc);
   HMONITOR newMonitor = MonitorFromWindow(m_hDeviceWnd, MONITOR_DEFAULTTONULL);
-  if (newMonitor != NULL && currentMonitor != newMonitor)
-    ResetRenderSystem(m_nBackBufferWidth, m_nBackBufferHeight, m_bFullScreenDevice, m_refreshRate);
-}
 
+  if (newMonitor != NULL && outputDesc.Monitor != newMonitor)
+  {
+    SetMonitor(newMonitor);
+    if (m_needNewDevice)
+    {
+      CLog::Log(LOGDEBUG, "%s - Adapter changed, reseting render system.", __FUNCTION__);
+      ResetRenderSystem(m_nBackBufferWidth, m_nBackBufferHeight, m_bFullScreenDevice, m_refreshRate);
+    }
+  }
+}
 
-bool CRenderSystemDX::IsSurfaceFormatOk(D3DFORMAT surfFormat, DWORD usage)
+void CRenderSystemDX::OnResize(unsigned int width, unsigned int height)
 {
-  // Verify the compatibility
-  HRESULT hr = m_pD3D->CheckDeviceFormat(m_adapter,
-                                         m_devType,
-                                         m_D3DPP.BackBufferFormat,
-                                         usage,
-                                         D3DRTYPE_SURFACE,
-                                         surfFormat);
-
-  return (SUCCEEDED(hr)) ? true : false;
+  if (!m_bRenderCreated)
+    return;
+
+  m_nBackBufferWidth = width;
+  m_nBackBufferHeight = height;
+  CreateWindowSizeDependentResources();
 }
 
-bool CRenderSystemDX::IsTextureFormatOk(D3DFORMAT texFormat, DWORD usage)
+void CRenderSystemDX::GetClosestDisplayModeToCurrent(IDXGIOutput* output, DXGI_MODE_DESC* outCurrentDisplayMode, bool useCached /*= false*/)
 {
-  // Verify the compatibility
-  HRESULT hr = m_pD3D->CheckDeviceFormat(m_adapter,
-                                         m_devType,
-                                         m_D3DPP.BackBufferFormat,
-                                         usage,
-                                         D3DRTYPE_TEXTURE,
-                                         texFormat);
-
-  return (SUCCEEDED(hr)) ? true : false;
+  DXGI_OUTPUT_DESC outputDesc;
+  output->GetDesc(&outputDesc);
+  HMONITOR hMonitor = outputDesc.Monitor;
+  MONITORINFOEX monitorInfo;
+  monitorInfo.cbSize = sizeof(MONITORINFOEX);
+  GetMonitorInfo(hMonitor, &monitorInfo);
+  DEVMODE devMode;
+  devMode.dmSize = sizeof(DEVMODE);
+  devMode.dmDriverExtra = 0;
+  EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode);
+
+  bool useDefaultRefreshRate = 1 == devMode.dmDisplayFrequency || 0 == devMode.dmDisplayFrequency;
+  float refreshRate = RATIONAL_TO_FLOAT(m_cachedMode.RefreshRate);
+
+  // this needed to improve performance for VideoSync bacause FindClosestMatchingMode is very slow
+  if (!useCached
+    || m_cachedMode.Width  != devMode.dmPelsWidth
+    || m_cachedMode.Height != devMode.dmPelsHeight
+    || long(refreshRate)   != devMode.dmDisplayFrequency)
+  {
+    DXGI_MODE_DESC current;
+    current.Width = devMode.dmPelsWidth;
+    current.Height = devMode.dmPelsHeight;
+    current.RefreshRate.Numerator = useDefaultRefreshRate ? 0 : devMode.dmDisplayFrequency;
+    current.RefreshRate.Denominator = useDefaultRefreshRate ? 0 : 1;
+    current.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+    current.ScanlineOrdering = m_interlaced ? DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST : DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
+    current.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+
+    output->FindClosestMatchingMode(&current, &m_cachedMode, m_pD3DDev);
+  }
+
+  ZeroMemory(outCurrentDisplayMode, sizeof(DXGI_MODE_DESC));
+  outCurrentDisplayMode->Width = m_cachedMode.Width;
+  outCurrentDisplayMode->Height = m_cachedMode.Height;
+  outCurrentDisplayMode->RefreshRate.Numerator = m_cachedMode.RefreshRate.Numerator;
+  outCurrentDisplayMode->RefreshRate.Denominator = m_cachedMode.RefreshRate.Denominator;
+  outCurrentDisplayMode->Format = m_cachedMode.Format;
+  outCurrentDisplayMode->ScanlineOrdering = m_cachedMode.ScanlineOrdering;
+  outCurrentDisplayMode->Scaling = m_cachedMode.Scaling;
 }
 
-BOOL CRenderSystemDX::IsDepthFormatOk(D3DFORMAT DepthFormat, D3DFORMAT RenderTargetFormat)
+void CRenderSystemDX::GetDisplayMode(DXGI_MODE_DESC *mode, bool useCached /*= false*/)
 {
-  // Verify that the depth format exists
-  if (!IsSurfaceFormatOk(DepthFormat, D3DUSAGE_DEPTHSTENCIL))
-    return false;
-
-  // Verify that the depth format is compatible
-  HRESULT hr = m_pD3D->CheckDepthStencilMatch(m_adapter,
-                                      m_devType,
-                                      m_D3DPP.BackBufferFormat,
-                                      RenderTargetFormat,
-                                      DepthFormat);
+  GetClosestDisplayModeToCurrent(m_pOutput, mode, useCached);
+}
 
-  return SUCCEEDED(hr);
+inline void DXWait(ID3D11Device* pDevice, ID3D11DeviceContext* pContext)
+{
+  ID3D11Query* wait = NULL;
+  CD3D11_QUERY_DESC qd(D3D11_QUERY_EVENT);
+  if (SUCCEEDED(pDevice->CreateQuery(&qd, &wait)))
+  {
+    pContext->End(wait);
+    while (S_FALSE == pContext->GetData(wait, NULL, 0, 0))
+      Sleep(1);
+  }
+  SAFE_RELEASE(wait);
 }
 
-void CRenderSystemDX::BuildPresentParameters()
+void CRenderSystemDX::SetFullScreenInternal()
 {
-  OSVERSIONINFOEX osvi;
-  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
-  osvi.dwOSVersionInfoSize = sizeof(osvi);
-  GetVersionEx((OSVERSIONINFO *)&osvi);
+  if (!m_bRenderCreated)
+    return;
 
-  ZeroMemory( &m_D3DPP, sizeof(D3DPRESENT_PARAMETERS) );
-  m_D3DPP.Windowed           = m_useWindowedDX;
-  m_D3DPP.SwapEffect         = D3DSWAPEFFECT_FLIP;
-  m_D3DPP.BackBufferCount    = 2;
+  HRESULT hr;
+  BOOL bFullScreen;
+  m_pSwapChain->GetFullscreenState(&bFullScreen, NULL);
 
-  if(m_useD3D9Ex && (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 1 || osvi.dwMajorVersion > 6))
+  // full-screen to windowed translation. Only change FS state and return
+  if (!!bFullScreen && m_useWindowedDX)
   {
-#if D3DX_SDK_VERSION >= 42
-    //m_D3DPP.SwapEffect       = D3DSWAPEFFECT_FLIPEX;
-#else
-#   pragma message("D3D SDK version is too old to support D3DSWAPEFFECT_FLIPEX")
-    CLog::Log(LOGWARNING, "CRenderSystemDX::BuildPresentParameters - xbmc compiled with an d3d sdk not supporting D3DSWAPEFFECT_FLIPEX");
-#endif
+    CLog::Log(LOGDEBUG, "%s - Switching swap chain to windowed mode.", __FUNCTION__);
+    hr = m_pSwapChain->SetFullscreenState(false, NULL);
+    m_bResizeRequred = S_OK == hr;
+
+    if (S_OK != hr)
+      CLog::Log(LOGERROR, "%s - Failed switch full screen state: %s.", __FUNCTION__, GetErrorDescription(hr).c_str());
+    // wait until switching screen state is done
+    DXWait(m_pD3DDev, m_pImdContext);
+    return;
   }
 
-  m_D3DPP.hDeviceWindow      = m_hDeviceWnd;
-  m_D3DPP.BackBufferWidth    = m_nBackBufferWidth;
-  m_D3DPP.BackBufferHeight   = m_nBackBufferHeight;
-  m_D3DPP.Flags              = D3DPRESENTFLAG_VIDEO;
-  m_D3DPP.PresentationInterval = (m_bVSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
-  m_D3DPP.FullScreen_RefreshRateInHz = (m_useWindowedDX) ? 0 : (int)m_refreshRate;
-  m_D3DPP.BackBufferFormat   = D3DFMT_X8R8G8B8;
-  m_D3DPP.MultiSampleType    = D3DMULTISAMPLE_NONE;
-  m_D3DPP.MultiSampleQuality = 0;
-
-  D3DFORMAT zFormat = D3DFMT_D16;
-  if      (IsDepthFormatOk(D3DFMT_D32, m_D3DPP.BackBufferFormat))           zFormat = D3DFMT_D32;
-  else if (IsDepthFormatOk(D3DFMT_D24S8, m_D3DPP.BackBufferFormat))         zFormat = D3DFMT_D24S8;
-  else if (IsDepthFormatOk(D3DFMT_D24X4S4, m_D3DPP.BackBufferFormat))       zFormat = D3DFMT_D24X4S4;
-  else if (IsDepthFormatOk(D3DFMT_D24X8, m_D3DPP.BackBufferFormat))         zFormat = D3DFMT_D24X8;
-  else if (IsDepthFormatOk(D3DFMT_D16, m_D3DPP.BackBufferFormat))           zFormat = D3DFMT_D16;
-  else if (IsDepthFormatOk(D3DFMT_D15S1, m_D3DPP.BackBufferFormat))         zFormat = D3DFMT_D15S1;
-
-  m_D3DPP.EnableAutoDepthStencil = TRUE;
-  m_D3DPP.AutoDepthStencilFormat = zFormat;
-
-  if (m_useD3D9Ex)
+  // true full-screen
+  if (m_bFullScreenDevice && !m_useWindowedDX)
   {
-    ZeroMemory( &m_D3DDMEX, sizeof(D3DDISPLAYMODEEX) );
-    m_D3DDMEX.Size             = sizeof(D3DDISPLAYMODEEX);
-    m_D3DDMEX.Width            = m_D3DPP.BackBufferWidth;
-    m_D3DDMEX.Height           = m_D3DPP.BackBufferHeight;
-    m_D3DDMEX.RefreshRate      = m_D3DPP.FullScreen_RefreshRateInHz;
-    m_D3DDMEX.Format           = m_D3DPP.BackBufferFormat;
-    m_D3DDMEX.ScanLineOrdering = m_interlaced ? D3DSCANLINEORDERING_INTERLACED : D3DSCANLINEORDERING_PROGRESSIVE;
+    IDXGIOutput* pOutput = NULL;
+    m_pSwapChain->GetContainingOutput(&pOutput);
+
+    DXGI_OUTPUT_DESC trgDesc, currDesc;
+    m_pOutput->GetDesc(&trgDesc);
+    pOutput->GetDesc(&currDesc);
+
+    if (trgDesc.Monitor != currDesc.Monitor || !bFullScreen)
+    {
+      // swap chain requires to change FS mode after resize or transition from windowed to full-screen.
+      CLog::Log(LOGDEBUG, "%s - Switching swap chain to fullscreen state.", __FUNCTION__);
+      hr = m_pSwapChain->SetFullscreenState(true, m_pOutput);
+      m_bResizeRequred = S_OK == hr;
+
+      if (S_OK != hr)
+        CLog::Log(LOGERROR, "%s - Failed switch full screen state: %s.", __FUNCTION__, GetErrorDescription(hr).c_str());
+    }
+    SAFE_RELEASE(pOutput);
+
+    // do not change modes if hw stereo
+    if (g_graphicsContext.GetStereoMode() == RENDER_STEREO_MODE_HARDWAREBASED)
+      return;
+
+    DXGI_SWAP_CHAIN_DESC scDesc;
+    m_pSwapChain->GetDesc(&scDesc);
+
+    DXGI_MODE_DESC currentMode, // closest to current mode
+      toMatchMode,              // required mode
+      matchedMode;              // closest to required mode
+
+    // find current mode on target output
+    GetClosestDisplayModeToCurrent(m_pOutput, &currentMode);
+
+    float currentRefreshRate = RATIONAL_TO_FLOAT(currentMode.RefreshRate);
+    CLog::Log(LOGDEBUG, "%s - Current display mode is: %dx%d@%0.3f", __FUNCTION__, currentMode.Width, currentMode.Height, currentRefreshRate);
+
+    // use backbuffer dimention to find required display mode
+    toMatchMode.Width = m_nBackBufferWidth;
+    toMatchMode.Height = m_nBackBufferHeight;
+    bool useDefaultRefreshRate = 0 == m_refreshRate;
+    toMatchMode.RefreshRate.Numerator = useDefaultRefreshRate ? 0 : m_refreshRate;
+    toMatchMode.RefreshRate.Denominator = useDefaultRefreshRate ? 0 : 1;
+    toMatchMode.Format = scDesc.BufferDesc.Format;
+    toMatchMode.Scaling = scDesc.BufferDesc.Scaling;
+    toMatchMode.ScanlineOrdering = scDesc.BufferDesc.ScanlineOrdering;
+
+    // find closest mode
+    m_pOutput->FindClosestMatchingMode(&toMatchMode, &matchedMode, m_pD3DDev);
+
+    float matchedRefreshRate = RATIONAL_TO_FLOAT(matchedMode.RefreshRate);
+    CLog::Log(LOGDEBUG, "%s - Found matched mode: %dx%d@%0.3f", __FUNCTION__, matchedMode.Width, matchedMode.Height, matchedRefreshRate);
+
+    // change mode if required (current != required)
+    if ( currentMode.Width != matchedMode.Width
+      || currentMode.Height != matchedMode.Height
+      || currentRefreshRate != matchedRefreshRate)
+    {
+      CLog::Log(LOGDEBUG, "%s - Switching mode to %dx%d@%0.3f.", __FUNCTION__, matchedMode.Width, matchedMode.Height, matchedRefreshRate);
+
+      // resize window (in windowed mode) or monitor resolution (in fullscreen mode) to required mode
+      hr = m_pSwapChain->ResizeTarget(&matchedMode);
+      m_bResizeRequred = S_OK == hr;
+
+      if (FAILED(hr))
+        CLog::Log(LOGERROR, "%s - Failed to switch output mode: %s", __FUNCTION__, GetErrorDescription(hr).c_str());
+    }
+
+    // wait until switching screen state is done
+    DXWait(m_pD3DDev, m_pImdContext);
   }
 }
 
-bool CRenderSystemDX::DestroyRenderSystem()
+bool CRenderSystemDX::IsFormatSupport(DXGI_FORMAT format, unsigned int usage)
 {
-  DeleteDevice();
+  UINT supported;
+  m_pD3DDev->CheckFormatSupport(format, &supported);
+  return (supported & usage) != 0;
+}
 
-  SAFE_RELEASE(m_stateBlock);
-  SAFE_RELEASE(m_pD3D);
-  SAFE_RELEASE(m_pD3DDevice);
+bool CRenderSystemDX::DestroyRenderSystem()
+{
+  if (m_pSwapChain)
+    m_pSwapChain->SetFullscreenState(false, NULL);
 
-  m_bRenderCreated = false;
+  DeleteDevice();
 
+  SAFE_RELEASE(m_pOutput);
+  SAFE_RELEASE(m_adapter);
+  SAFE_RELEASE(m_dxgiFactory);
+#ifdef _DEBUG
+  if (m_d3dDebug)
+  {
+    m_d3dDebug->ReportLiveDeviceObjects(D3D11_RLDO_SUMMARY | D3D11_RLDO_DETAIL);
+    m_d3dDebug->Release();
+  }
+#endif
   return true;
 }
 
@@ -325,11 +429,42 @@ void CRenderSystemDX::DeleteDevice()
 {
   CSingleLock lock(m_resourceSection);
 
+  if (m_pGUIShader)
+    m_pGUIShader->End();
+
   // tell any shared resources
-  for (vector<ID3DResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
+  for (std::vector<ID3DResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
     (*i)->OnDestroyDevice();
 
-  SAFE_RELEASE(m_pD3DDevice);
+  SAFE_DELETE(m_pGUIShader);
+  SAFE_RELEASE(m_pTextureRight);
+  SAFE_RELEASE(m_pRenderTargetViewRight);
+  SAFE_RELEASE(m_pShaderResourceViewRight);
+  SAFE_RELEASE(m_BlendEnableState);
+  SAFE_RELEASE(m_BlendDisableState);
+  SAFE_RELEASE(m_RSScissorDisable);
+  SAFE_RELEASE(m_RSScissorEnable);
+  SAFE_RELEASE(m_depthStencilState);
+  SAFE_RELEASE(m_depthStencilView);
+  SAFE_RELEASE(m_pRenderTargetView);
+  SAFE_RELEASE(m_pSwapChain);
+  SAFE_RELEASE(m_pSwapChain1);
+  SAFE_RELEASE(m_pD3DDev);
+  if (m_pContext && m_pContext != m_pImdContext)
+  {
+    FinishCommandList(false);
+    m_pContext->ClearState();
+    m_pContext->Flush();
+    SAFE_RELEASE(m_pContext);
+  }
+  if (m_pImdContext)
+  {
+    m_pImdContext->ClearState();
+    m_pImdContext->Flush();
+    SAFE_RELEASE(m_pImdContext);
+  }
+  m_bResizeRequred = false;
+  m_bHWStereoEnabled = false;
   m_bRenderCreated = false;
 }
 
@@ -337,14 +472,13 @@ void CRenderSystemDX::OnDeviceLost()
 {
   CSingleLock lock(m_resourceSection);
   g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_RENDERER_LOST);
-  SAFE_RELEASE(m_stateBlock);
 
   if (m_needNewDevice)
     DeleteDevice();
   else
   {
     // just resetting the device
-    for (vector<ID3DResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
+    for (std::vector<ID3DResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
       (*i)->OnLostDevice();
   }
 }
@@ -356,175 +490,179 @@ void CRenderSystemDX::OnDeviceReset()
   if (m_needNewDevice)
     CreateDevice();
   else
-  {
-    // just need a reset
-    if (m_useD3D9Ex)
-      m_nDeviceStatus = ((IDirect3DDevice9Ex*)m_pD3DDevice)->ResetEx(&m_D3DPP, m_D3DPP.Windowed ? NULL : &m_D3DDMEX);
-    else
-      m_nDeviceStatus = m_pD3DDevice->Reset(&m_D3DPP);
-  }
-
-  if (m_nDeviceStatus == S_OK)
   { // we're back
-    for (vector<ID3DResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
+    for (std::vector<ID3DResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
       (*i)->OnResetDevice();
 
     g_renderManager.Flush();
-
     g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_RENDERER_RESET);
   }
-  else
-  {
-    for (vector<ID3DResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
-      (*i)->OnLostDevice();
-  }
 }
 
 bool CRenderSystemDX::CreateDevice()
 {
-  // Code based on Ogre 3D engine
   CSingleLock lock(m_resourceSection);
 
   HRESULT hr;
 
-  if(m_pD3D == NULL)
-    return false;
-
-  if(m_hDeviceWnd == NULL)
-    return false;
+  SAFE_RELEASE(m_pD3DDev);
 
-  CLog::Log(LOGDEBUG, __FUNCTION__" on adapter %d", m_adapter);
+  D3D_FEATURE_LEVEL featureLevels[] =
+  {
+    D3D_FEATURE_LEVEL_11_1,
+    D3D_FEATURE_LEVEL_11_0,
+    D3D_FEATURE_LEVEL_9_3,
+    D3D_FEATURE_LEVEL_9_2,
+    D3D_FEATURE_LEVEL_9_1,
+  };
 
-  BuildPresentParameters();
+  // the VIDEO_SUPPORT flag force lowering feature level if current env not support video on 11_1
+  UINT createDeviceFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; 
+#ifdef _DEBUG
+  createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
 
-  D3DCAPS9 caps;
-  memset(&caps, 0, sizeof(caps));
-  m_pD3D->GetDeviceCaps(m_adapter, m_devType, &caps);
+  // we should specify D3D_DRIVER_TYPE_UNKNOWN if create device with specified adapter.
+  hr = D3D11CreateDevice(m_adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, createDeviceFlags, featureLevels, ARRAYSIZE(featureLevels), 
+                         D3D11_SDK_VERSION, &m_pD3DDev, &m_featureLevel, &m_pImdContext);
 
-  DWORD VertexProcessingFlags = 0;
-  if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
-  {
-    /* Activate when the state management of the fixed pipeline is in order,
-      to get a bit more performance
-    if (caps.DevCaps & D3DDEVCAPS_PUREDEVICE)
-      VertexProcessingFlags = D3DCREATE_PUREDEVICE;
-    */
-    VertexProcessingFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
-    CLog::Log(LOGDEBUG, __FUNCTION__" - using hardware vertex processing");
-  }
-  else
+  if (FAILED(hr))
   {
-    VertexProcessingFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
-    CLog::Log(LOGDEBUG, __FUNCTION__" - using software vertex processing");
-  }
+    CLog::Log(LOGDEBUG, "%s - First try to create device failed with error: %s.", __FUNCTION__, GetErrorDescription(hr).c_str());
 
-  if (m_useD3D9Ex)
-  {
-    hr = ((IDirect3D9Ex*)m_pD3D)->CreateDeviceEx(m_adapter, m_devType, m_hFocusWnd,
-      VertexProcessingFlags | D3DCREATE_MULTITHREADED, &m_D3DPP, m_D3DPP.Windowed ? NULL : &m_D3DDMEX, (IDirect3DDevice9Ex**)&m_pD3DDevice );
-    if (FAILED(hr))
+    for (int i = 1; i < ARRAYSIZE(featureLevels); i++)
     {
-      CLog::Log(LOGWARNING, __FUNCTION__" - initial wanted device config failed");
-      // Try a second time, may fail the first time due to back buffer count,
-      // which will be corrected down to 1 by the runtime
-      hr = ((IDirect3D9Ex*)m_pD3D)->CreateDeviceEx( m_adapter, m_devType, m_hFocusWnd,
-        VertexProcessingFlags | D3DCREATE_MULTITHREADED, &m_D3DPP, m_D3DPP.Windowed ? NULL : &m_D3DDMEX, (IDirect3DDevice9Ex**)&m_pD3DDevice );
-      if( FAILED( hr ) )
-      {
-        CLog::Log(LOGERROR, __FUNCTION__" - unable to create a device. %s", GetErrorDescription(hr).c_str());
-        return false;
-      }
+      CLog::Log(LOGDEBUG, "%s - Trying to create device with lowest feature level: %#x.", __FUNCTION__, featureLevels[i]);
+      // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
+      hr = D3D11CreateDevice(m_adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, createDeviceFlags, &featureLevels[i], ARRAYSIZE(featureLevels) - i,
+                             D3D11_SDK_VERSION, &m_pD3DDev, &m_featureLevel, &m_pImdContext);
+      if (SUCCEEDED(hr))
+        break;
+
+      CLog::Log(LOGDEBUG, "%s - Next try to create device failed with error: %s.", __FUNCTION__, GetErrorDescription(hr).c_str());
     }
-    // Not sure the following actually does something
-    ((IDirect3DDevice9Ex*)m_pD3DDevice)->SetGPUThreadPriority(7);
   }
-  else
+
+  if (FAILED(hr))
   {
-    hr = m_pD3D->CreateDevice(m_adapter, m_devType, m_hFocusWnd,
-      VertexProcessingFlags | D3DCREATE_MULTITHREADED, &m_D3DPP, &m_pD3DDevice );
-    if (FAILED(hr))
-    {
-      CLog::Log(LOGWARNING, __FUNCTION__" - initial wanted device config failed");
-      // Try a second time, may fail the first time due to back buffer count,
-      // which will be corrected down to 1 by the runtime
-      hr = m_pD3D->CreateDevice( m_adapter, m_devType, m_hFocusWnd,
-        VertexProcessingFlags | D3DCREATE_MULTITHREADED, &m_D3DPP, &m_pD3DDevice );
-      if( FAILED( hr ) )
-      {
-        CLog::Log(LOGERROR, __FUNCTION__" - unable to create a device. %s", GetErrorDescription(hr).c_str());
-        return false;
-      }
-    }
+    CLog::Log(LOGERROR, "%s - D3D11 device creation failure with error %s.", __FUNCTION__, GetErrorDescription(hr).c_str());
+    return false;
   }
 
-  if(m_pD3D->GetAdapterIdentifier(m_adapter, 0, &m_AIdentifier) == D3D_OK)
+  if ( g_advancedSettings.m_bAllowDeferredRendering 
+    && FAILED(m_pD3DDev->CreateDeferredContext(0, &m_pContext)))
   {
-    m_RenderRenderer = (const char*)m_AIdentifier.Description;
-    m_RenderVendor   = (const char*)m_AIdentifier.Driver;
-    m_RenderVersion = StringUtils::Format("%d.%d.%d.%04d", HIWORD(m_AIdentifier.DriverVersion.HighPart), LOWORD(m_AIdentifier.DriverVersion.HighPart),
-                                                           HIWORD(m_AIdentifier.DriverVersion.LowPart) , LOWORD(m_AIdentifier.DriverVersion.LowPart));
+    CLog::Log(LOGERROR, "%s - Failed to create deferred context, deferred rendering is not possible, fallback to immediate rendering.", __FUNCTION__);
   }
 
-  CLog::Log(LOGDEBUG, __FUNCTION__" - adapter %d: %s, %s, VendorId %lu, DeviceId %lu",
-            m_adapter, m_AIdentifier.Driver, m_AIdentifier.Description, m_AIdentifier.VendorId, m_AIdentifier.DeviceId);
-
-  // get our render capabilities
-  // re-read caps, there may be changes depending on the vertex processing type
-  m_pD3DDevice->GetDeviceCaps(&caps);
+  // make immediate context as default context if deferred context was not created
+  if (!m_pContext)
+    m_pContext = m_pImdContext;
+
+  if (m_featureLevel < D3D_FEATURE_LEVEL_9_3)
+    m_maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+  else if (m_featureLevel < D3D_FEATURE_LEVEL_10_0)
+    m_maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+  else if (m_featureLevel < D3D_FEATURE_LEVEL_11_0)
+    m_maxTextureSize = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+  else 
+    // 11_x and greater feature level. Limit this size to avoid memory overheads
+    m_maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION >> 1;
+
+  // use multi-thread protection on the device context to prevent deadlock issues that can sometimes happen
+  // when decoder call ID3D11VideoContext::GetDecoderBuffer or ID3D11VideoContext::ReleaseDecoderBuffer.
+  ID3D10Multithread *pMultiThreading = NULL;
+  if (SUCCEEDED(m_pD3DDev->QueryInterface(__uuidof(ID3D10Multithread), reinterpret_cast<void**>(&pMultiThreading))))
+  {
+    pMultiThreading->SetMultithreadProtected(true);
+    pMultiThreading->Release();
+  }
 
-  m_maxTextureSize = min(caps.MaxTextureWidth, caps.MaxTextureHeight);
+  IDXGIDevice1* pDXGIDevice = NULL;
+  if (SUCCEEDED(m_pD3DDev->QueryInterface(__uuidof(IDXGIDevice1), reinterpret_cast<void**>(&pDXGIDevice))))
+  {
+    // Not sure the following actually does something but this exists in dx9 implementation
+    pDXGIDevice->SetGPUThreadPriority(7);
+    // Ensure that DXGI does not queue more than one frame at a time. This both reduces
+    // latency and ensures that the application will only render after each VSync
+    pDXGIDevice->SetMaximumFrameLatency(1);
+    SAFE_RELEASE(pDXGIDevice);
+  }
 
-  if (g_advancedSettings.m_AllowDynamicTextures && m_useD3D9Ex && (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES))
+#ifdef _DEBUG
+  if (SUCCEEDED(m_pD3DDev->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(&m_d3dDebug))))
   {
-    m_defaultD3DUsage = D3DUSAGE_DYNAMIC;
-    m_defaultD3DPool  = D3DPOOL_DEFAULT;
-    CLog::Log(LOGDEBUG, __FUNCTION__" - using D3DCAPS2_DYNAMICTEXTURES");
+    ID3D11InfoQueue *d3dInfoQueue = nullptr;
+    if (SUCCEEDED(m_d3dDebug->QueryInterface(__uuidof(ID3D11InfoQueue), reinterpret_cast<void**>(&d3dInfoQueue))))
+    {
+      D3D11_MESSAGE_ID hide[] =
+      {
+        D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED,  // avoid DXGI_FORMAT_A8_UNORM error
+        D3D11_MESSAGE_ID_GETVIDEOPROCESSORFILTERRANGE_UNSUPPORTED,        // avoid GETVIDEOPROCESSORFILTERRANGE_UNSUPPORTED (dx bug)
+        D3D11_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_NEGATIVESCISSOR         // avoid warning for some labels out of screen
+        // Add more message IDs here as needed
+      };
+
+      D3D11_INFO_QUEUE_FILTER filter;
+      ZeroMemory(&filter, sizeof(filter));
+      filter.DenyList.NumIDs = _countof(hide);
+      filter.DenyList.pIDList = hide;
+      d3dInfoQueue->AddStorageFilterEntries(&filter);
+      d3dInfoQueue->Release();
+    }
   }
-  else
+#endif
+
+  m_adapterDesc = {};
+  if (SUCCEEDED(m_adapter->GetDesc(&m_adapterDesc)))
   {
-    m_defaultD3DUsage = 0;
-    m_defaultD3DPool  = D3DPOOL_MANAGED;
+    CLog::Log(LOGDEBUG, "%s - on adapter %S (VendorId: %#x DeviceId: %#x) with feature level %#x.", __FUNCTION__, 
+                        m_adapterDesc.Description, m_adapterDesc.VendorId, m_adapterDesc.DeviceId, m_featureLevel);
+
+    m_RenderRenderer = StringUtils::Format("%S", m_adapterDesc.Description);
+    IDXGIFactory2* dxgiFactory2 = nullptr;
+    m_dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2));
+    m_RenderVersion = StringUtils::Format("DirectX %s (FL %d.%d)", 
+                                          dxgiFactory2 != nullptr ? "11.1" : "11.0", 
+                                          (m_featureLevel >> 12) & 0xF, 
+                                          (m_featureLevel >> 8) & 0xF);
+    SAFE_RELEASE(dxgiFactory2);
   }
 
   m_renderCaps = 0;
-
-  CLog::Log(LOGDEBUG, __FUNCTION__" - texture caps: 0x%08X", caps.TextureCaps);
-
-  if(IsTextureFormatOk(D3DFMT_DXT1, m_defaultD3DUsage)
-  && IsTextureFormatOk(D3DFMT_DXT3, m_defaultD3DUsage)
-  && IsTextureFormatOk(D3DFMT_DXT5, m_defaultD3DUsage))
+  unsigned int usage = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
+  if ( IsFormatSupport(DXGI_FORMAT_BC1_UNORM, usage)
+    && IsFormatSupport(DXGI_FORMAT_BC2_UNORM, usage)
+    && IsFormatSupport(DXGI_FORMAT_BC3_UNORM, usage))
     m_renderCaps |= RENDER_CAPS_DXT;
 
-  if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0)
-  { // we're allowed NPOT textures
-    m_renderCaps |= RENDER_CAPS_NPOT;
-    if (((m_renderCaps & RENDER_CAPS_DXT) != 0) && ((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0))
-      m_renderCaps |= RENDER_CAPS_DXT_NPOT;
-  }
-  else if ((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) != 0)
-  { // we're allowed _some_ NPOT textures (namely non-DXT and only with D3DTADDRESS_CLAMP and no wrapping)
-    m_renderCaps |= RENDER_CAPS_NPOT;
-  }
+  // MSDN: At feature levels 9_1, 9_2 and 9_3, the display device supports the use of 2D textures with dimensions that are not powers of two under two conditions.
+  // First, only one MIP-map level for each texture can be created - we are using only 1 mip level)
+  // Second, no wrap sampler modes for textures are allowed - we are using clamp everywhere
+  // At feature levels 10_0, 10_1 and 11_0, the display device unconditionally supports the use of 2D textures with dimensions that are not powers of two.
+  // so, setup caps NPOT
+  m_renderCaps |= RENDER_CAPS_NPOT;
+  if ((m_renderCaps & RENDER_CAPS_DXT) != 0)
+    m_renderCaps |= RENDER_CAPS_DXT_NPOT;
 
   // Temporary - allow limiting the caps to debug a texture problem
   if (g_advancedSettings.m_RestrictCapsMask != 0)
     m_renderCaps &= ~g_advancedSettings.m_RestrictCapsMask;
 
   if (m_renderCaps & RENDER_CAPS_DXT)
-    CLog::Log(LOGDEBUG, __FUNCTION__" - RENDER_CAPS_DXT");
+    CLog::Log(LOGDEBUG, "%s - RENDER_CAPS_DXT", __FUNCTION__);
   if (m_renderCaps & RENDER_CAPS_NPOT)
-    CLog::Log(LOGDEBUG, __FUNCTION__" - RENDER_CAPS_NPOT");
+    CLog::Log(LOGDEBUG, "%s - RENDER_CAPS_NPOT", __FUNCTION__);
   if (m_renderCaps & RENDER_CAPS_DXT_NPOT)
-    CLog::Log(LOGDEBUG, __FUNCTION__" - RENDER_CAPS_DXT_NPOT");
+    CLog::Log(LOGDEBUG, "%s - RENDER_CAPS_DXT_NPOT", __FUNCTION__);
 
+  /* All the following quirks need to be tested
   // nVidia quirk: some NPOT DXT textures of the GUI display with corruption
   // when using D3DPOOL_DEFAULT + D3DUSAGE_DYNAMIC textures (no other choice with D3D9Ex for example)
   // most likely xbmc bug, but no hw to repro & fix properly.
   // affects lots of hw generations - 6xxx, 7xxx, GT220, ION1
   // see ticket #9269
-  if(m_defaultD3DUsage == D3DUSAGE_DYNAMIC
-  && m_defaultD3DPool  == D3DPOOL_DEFAULT
-  && m_AIdentifier.VendorId == PCIV_nVidia)
+  if (m_adapterDesc.VendorId == PCIV_nVidia)
   {
     CLog::Log(LOGDEBUG, __FUNCTION__" - nVidia workaround - disabling RENDER_CAPS_DXT_NPOT");
     m_renderCaps &= ~RENDER_CAPS_DXT_NPOT;
@@ -536,180 +674,536 @@ bool CRenderSystemDX::CreateDevice()
   // DXT3/5: 16 pixels wide ----------------------------------------
   // Both equal to a pitch of 64. So far no Intel has DXT NPOT (including i3/i5/i7, so just go with the next higher POT.
   // See ticket #9578
-  if(m_defaultD3DUsage == D3DUSAGE_DYNAMIC
-  && m_defaultD3DPool  == D3DPOOL_DEFAULT
-  && m_AIdentifier.VendorId == PCIV_Intel)
+  if (m_adapterDesc.VendorId == PCIV_Intel)
   {
     CLog::Log(LOGDEBUG, __FUNCTION__" - Intel workaround - specifying minimum pitch for compressed textures.");
     m_minDXTPitch = 128;
-  }
-
-  D3DDISPLAYMODE mode;
-  if (SUCCEEDED(m_pD3DDevice->GetDisplayMode(0, &mode)))
-    m_screenHeight = mode.Height;
-  else
-    m_screenHeight = m_nBackBufferHeight;
+  }*/
 
-  m_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
-  m_pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+  if (!CreateStates() || !InitGUIShader() || !CreateWindowSizeDependentResources())
+    return false;
 
   m_bRenderCreated = true;
   m_needNewDevice = false;
 
   // tell any shared objects about our resurrection
-  for (vector<ID3DResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
+  for (std::vector<ID3DResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
     (*i)->OnCreateDevice();
 
+  RestoreViewPort();
+
   return true;
 }
 
-bool CRenderSystemDX::PresentRenderImpl(const CDirtyRegionList &dirty)
+bool CRenderSystemDX::CreateWindowSizeDependentResources()
 {
+  if (m_resizeInProgress)
+    return false;
+
   HRESULT hr;
+  DXGI_SWAP_CHAIN_DESC scDesc = { 0 };
 
-  if (!m_bRenderCreated)
-    return false;
+  bool bNeedRecreate = false;
+  bool bNeedResize   = false;
+  bool bHWStereoEnabled = RENDER_STEREO_MODE_HARDWAREBASED == g_graphicsContext.GetStereoMode();
 
-  if(m_nDeviceStatus != S_OK)
-    return false;
+  if (m_pSwapChain)
+  {
+    m_pSwapChain->GetDesc(&scDesc);
+    bNeedResize = m_bResizeRequred || m_nBackBufferWidth != scDesc.BufferDesc.Width || m_nBackBufferHeight != scDesc.BufferDesc.Height;
+  }
+  else
+    bNeedResize = true;
 
-  //CVideoReferenceClock polls GetRasterStatus too,
-  //polling it from two threads at the same time is bad
-  if (g_advancedSettings.m_sleepBeforeFlip > 0 && !g_VideoReferenceClock.IsRunning())
+  if (m_pSwapChain1)
   {
-    //save current thread priority and set thread priority to THREAD_PRIORITY_TIME_CRITICAL
-    int priority = GetThreadPriority(GetCurrentThread());
-    if (priority != THREAD_PRIORITY_ERROR_RETURN)
-      SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
+    DXGI_SWAP_CHAIN_DESC1 scDesc;
+    m_pSwapChain1->GetDesc1(&scDesc);
+    bNeedRecreate = (scDesc.Stereo && !bHWStereoEnabled) || (!scDesc.Stereo && bHWStereoEnabled);
+  }
+
+  if (!bNeedRecreate && !bNeedResize)
+  {
+    CheckInterlasedStereoView();
+    return true;
+  }
 
-    D3DRASTER_STATUS rasterStatus;
-    int64_t          prev = CurrentHostCounter();
+  m_resizeInProgress = true;
+
+  CLog::Log(LOGDEBUG, "%s - (Re)Create window size (%dx%d) dependent resources.", __FUNCTION__, m_nBackBufferWidth, m_nBackBufferHeight);
+
+  bool bRestoreRTView = false;
+  {
+    ID3D11RenderTargetView* pRTView; ID3D11DepthStencilView* pDSView;
+    m_pContext->OMGetRenderTargets(1, &pRTView, &pDSView);
 
-    while (SUCCEEDED(m_pD3DDevice->GetRasterStatus(0, &rasterStatus)))
+    bRestoreRTView = NULL != pRTView || NULL != pDSView;
+
+    SAFE_RELEASE(pRTView);
+    SAFE_RELEASE(pDSView);
+  }
+
+  m_pContext->OMSetRenderTargets(0, NULL, NULL);
+  FinishCommandList(false);
+
+  SAFE_RELEASE(m_pRenderTargetView);
+  SAFE_RELEASE(m_depthStencilView);
+  SAFE_RELEASE(m_pRenderTargetViewRight);
+  SAFE_RELEASE(m_pShaderResourceViewRight);
+  SAFE_RELEASE(m_pTextureRight);
+
+  if (bNeedRecreate)
+  {
+    BOOL fullScreen;
+    m_pSwapChain1->GetFullscreenState(&fullScreen, NULL);
+    if (fullScreen)
+      m_pSwapChain1->SetFullscreenState(false, NULL);
+
+    CLog::Log(LOGDEBUG, "%s - Destroying swapchain in order to switch %s stereoscopic 3D.", __FUNCTION__, bHWStereoEnabled ? "to" : "from");
+
+    SAFE_RELEASE(m_pSwapChain);
+    SAFE_RELEASE(m_pSwapChain1);
+    m_pImdContext->Flush();
+
+    // flush command is asynchronous, so wait until destruction is completed
+    // otherwise it can cause problems with flip presentation model swap chains.
+    DXWait(m_pD3DDev, m_pImdContext);
+  }
+
+  if (!m_pSwapChain)
+  {
+    CLog::Log(LOGDEBUG, "%s - Creating swapchain in %s mode.", __FUNCTION__, bHWStereoEnabled ? "Stereoscopic 3D" : "Mono");
+
+    // Create swap chain
+    IDXGIFactory2* dxgiFactory2 = NULL;
+    hr = m_dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2));
+    if (SUCCEEDED(hr) && dxgiFactory2)
     {
-      //wait for the scanline to go over the given proportion of m_screenHeight mark
-      if (!rasterStatus.InVBlank && rasterStatus.ScanLine >= g_advancedSettings.m_sleepBeforeFlip * m_screenHeight)
-        break;
+      // DirectX 11.1 or later
+      DXGI_SWAP_CHAIN_DESC1 scDesc1 = { 0 };
+      scDesc1.Width       = m_nBackBufferWidth;
+      scDesc1.Height      = m_nBackBufferHeight;
+      scDesc1.BufferCount = 2;  // Use double buffering to minimize latency.
+      scDesc1.Format      = DXGI_FORMAT_B8G8R8A8_UNORM;
+      scDesc1.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+      scDesc1.AlphaMode   = DXGI_ALPHA_MODE_UNSPECIFIED;
+      scDesc1.Stereo      = bHWStereoEnabled;
+      scDesc1.SwapEffect  = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+      scDesc1.Flags       = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+
+      scDesc1.SampleDesc.Count = 1;
+      scDesc1.SampleDesc.Quality = 0;
+
+      DXGI_SWAP_CHAIN_FULLSCREEN_DESC scFSDesc = { 0 };
+      scFSDesc.ScanlineOrdering = m_interlaced ? DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST : DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
+      scFSDesc.Windowed         = m_useWindowedDX;
+
+      hr = dxgiFactory2->CreateSwapChainForHwnd(m_pD3DDev, m_hFocusWnd, &scDesc1, &scFSDesc, NULL, &m_pSwapChain1);
+
+      if (SUCCEEDED(hr))
+      {
+        m_pSwapChain1->QueryInterface(__uuidof(IDXGISwapChain), reinterpret_cast<void**>(&m_pSwapChain));
+        m_bHWStereoEnabled = bHWStereoEnabled;
+      }
+      dxgiFactory2->Release();
 
-      //in theory it's possible this loop never exits, so don't let it run for longer than 100 ms
-      int64_t now = CurrentHostCounter();
-      if ((now - prev) * 10 > m_systemFreq)
-        break;
+      // this hackish way to disable stereo in windowed mode:
+      // - restart presenting, 0 in sync interval discards current frame also
+      // - wait until new frame will be drawn
+      // sleep value possible depends on hardware m.b. need a setting in as.xml
+      if (!bHWStereoEnabled && m_useWindowedDX && bNeedRecreate)
+      {
+        DXGI_PRESENT_PARAMETERS presentParams = {};
+        presentParams.DirtyRectsCount = 0;
+        presentParams.pDirtyRects = NULL;
+        presentParams.pScrollRect = NULL;
+        m_pSwapChain1->Present1(0, DXGI_PRESENT_RESTART, &presentParams);
 
-      Sleep(1);
+        Sleep(100);
+      }
+    }
+    else
+    {
+      // DirectX 11.0 systems
+      scDesc.BufferCount  = 2;  // Use double buffering to minimize latency.
+      scDesc.BufferUsage  = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+      scDesc.OutputWindow = m_hFocusWnd;
+      scDesc.Windowed     = m_useWindowedDX;
+      scDesc.SwapEffect   = DXGI_SWAP_EFFECT_SEQUENTIAL;
+      scDesc.Flags        = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+
+      scDesc.BufferDesc.Width   = m_nBackBufferWidth;
+      scDesc.BufferDesc.Height  = m_nBackBufferHeight;
+      scDesc.BufferDesc.Format  = DXGI_FORMAT_B8G8R8A8_UNORM;
+      scDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+      scDesc.BufferDesc.ScanlineOrdering = m_interlaced ? DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST : DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
+      scDesc.SampleDesc.Count = 1;
+      scDesc.SampleDesc.Quality = 0;
+
+      hr = m_dxgiFactory->CreateSwapChain(m_pD3DDev, &scDesc, &m_pSwapChain);
     }
 
-    //restore thread priority
-    if (priority != THREAD_PRIORITY_ERROR_RETURN)
-      SetThreadPriority(GetCurrentThread(), priority);
+    if (FAILED(hr))
+    {
+      CLog::Log(LOGERROR, "%s - Creating swap chain failed with error: %s.", __FUNCTION__, GetErrorDescription(hr).c_str());
+      m_bRenderCreated = false;
+      return false;
+    }
+
+    // tell DXGI to not interfere with application's handling of window mode changes
+    m_dxgiFactory->MakeWindowAssociation(m_hFocusWnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER);
   }
+  else
+  {
+    // resize swap chain buffers with preserving the existing buffer count and format.
+    hr = m_pSwapChain->ResizeBuffers(scDesc.BufferCount, m_nBackBufferWidth, m_nBackBufferHeight, scDesc.BufferDesc.Format, scDesc.Flags);
+    if (FAILED(hr))
+    {
+      CLog::Log(LOGERROR, "%s - Failed to resize buffers (%s).", __FUNCTION__, GetErrorDescription(hr).c_str());
+      if (DXGI_ERROR_DEVICE_REMOVED == hr)
+        OnDeviceLost();
 
-  hr = m_pD3DDevice->Present( NULL, NULL, 0, NULL );
+      return false;
+    }
+  }
 
-  if( D3DERR_DEVICELOST == hr )
+  // Create a render target view
+  ID3D11Texture2D* pBackBuffer = nullptr;
+  hr = m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pBackBuffer));
+  if (FAILED(hr))
   {
-    CLog::Log(LOGDEBUG, "%s - lost device", __FUNCTION__);
+    CLog::Log(LOGERROR, "%s - Failed to get back buffer (%s).", __FUNCTION__, GetErrorDescription(hr).c_str());
     return false;
   }
 
-  if(FAILED(hr))
+  // Create a view interface on the rendertarget to use on bind for mono or left eye view.
+  CD3D11_RENDER_TARGET_VIEW_DESC rtDesc(D3D11_RTV_DIMENSION_TEXTURE2DARRAY, DXGI_FORMAT_UNKNOWN, 0, 0, 1);
+  hr = m_pD3DDev->CreateRenderTargetView(pBackBuffer, &rtDesc, &m_pRenderTargetView);
+  if (FAILED(hr))
   {
-    CLog::Log(LOGDEBUG, "%s - Present failed. %s", __FUNCTION__, GetErrorDescription(hr).c_str());
+    CLog::Log(LOGERROR, "%s - Failed to create render target view (%s).", __FUNCTION__, GetErrorDescription(hr).c_str());
+    pBackBuffer->Release();
     return false;
   }
 
-  return true;
-}
+  if (m_bHWStereoEnabled)
+  {
+    // Stereo swapchains have an arrayed resource, so create a second Render Target for the right eye buffer.
+    CD3D11_RENDER_TARGET_VIEW_DESC rtDesc(D3D11_RTV_DIMENSION_TEXTURE2DARRAY, DXGI_FORMAT_UNKNOWN, 0, 1, 1);
+    hr = m_pD3DDev->CreateRenderTargetView(pBackBuffer, &rtDesc, &m_pRenderTargetViewRight);
+    if (FAILED(hr))
+    {
+      CLog::Log(LOGERROR, "%s - Failed to create right eye buffer (%s).", __FUNCTION__, GetErrorDescription(hr).c_str());
+      pBackBuffer->Release();
+      g_graphicsContext.SetStereoMode(RENDER_STEREO_MODE_OFF); // try fallback to mono
+    }
+  }
+  pBackBuffer->Release();
 
-bool CRenderSystemDX::BeginRender()
-{
-  if (!m_bRenderCreated)
+  DXGI_FORMAT zFormat = DXGI_FORMAT_D16_UNORM;
+  if      (IsFormatSupport(DXGI_FORMAT_D32_FLOAT, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))          zFormat = DXGI_FORMAT_D32_FLOAT;
+  else if (IsFormatSupport(DXGI_FORMAT_D24_UNORM_S8_UINT, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))  zFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
+  else if (IsFormatSupport(DXGI_FORMAT_D16_UNORM, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))          zFormat = DXGI_FORMAT_D16_UNORM;
+
+  ID3D11Texture2D* depthStencilBuffer = NULL;
+  // Initialize the description of the depth buffer.
+  CD3D11_TEXTURE2D_DESC depthBufferDesc(zFormat, m_nBackBufferWidth, m_nBackBufferHeight, 1, 1, D3D11_BIND_DEPTH_STENCIL);
+  // Create the texture for the depth buffer using the filled out description.
+  hr = m_pD3DDev->CreateTexture2D(&depthBufferDesc, NULL, &depthStencilBuffer);
+  if (FAILED(hr))
+  {
+    CLog::Log(LOGERROR, "%s - Failed to create depth stencil buffer (%s).", __FUNCTION__, GetErrorDescription(hr).c_str());
     return false;
+  }
 
-  HRESULT oldStatus = m_nDeviceStatus;
-  if (m_useD3D9Ex)
+  // Create the depth stencil view.
+  CD3D11_DEPTH_STENCIL_VIEW_DESC viewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
+  hr = m_pD3DDev->CreateDepthStencilView(depthStencilBuffer, &viewDesc, &m_depthStencilView);
+  depthStencilBuffer->Release();
+
+  if (FAILED(hr))
   {
-    m_nDeviceStatus = ((IDirect3DDevice9Ex*)m_pD3DDevice)->CheckDeviceState(m_hDeviceWnd);
+    CLog::Log(LOGERROR, "%s - Failed to create depth stencil view (%s).", __FUNCTION__, GetErrorDescription(hr).c_str());
+    return false;
+  }
 
-    // handling of new D3D9 extensions return values. Others fallback to regular D3D9 handling.
-    switch(m_nDeviceStatus)
-    {
-    case S_PRESENT_MODE_CHANGED:
-      // Timing leads us here on occasion.
-      BuildPresentParameters();
-      m_nDeviceStatus = ((IDirect3DDevice9Ex*)m_pD3DDevice)->ResetEx(&m_D3DPP, m_D3DPP.Windowed ? NULL : &m_D3DDMEX);
-      break;
-    case S_PRESENT_OCCLUDED:
-      m_nDeviceStatus = D3D_OK;
-      break;
-    case D3DERR_DEVICEHUNG:
-      CLog::Log(LOGERROR, "D3DERR_DEVICEHUNG");
-      m_nDeviceStatus = D3DERR_DEVICELOST;
-      m_needNewDevice = true;
-      break;
-    case D3DERR_OUTOFVIDEOMEMORY:
-      CLog::Log(LOGERROR, "D3DERR_OUTOFVIDEOMEMORY");
-      m_nDeviceStatus = D3DERR_DEVICELOST;
-      m_needNewDevice = true;
-      break;
-    case D3DERR_DEVICEREMOVED:
-      CLog::Log(LOGERROR, "D3DERR_DEVICEREMOVED");
-      m_nDeviceStatus = D3DERR_DEVICELOST;
-      m_needNewDevice = true;
-      // fixme: also needs to re-enumerate and switch to another screen
-      break;
-    }
+  if (m_viewPort.Height == 0 || m_viewPort.Width == 0)
+  {
+    CRect rect(0, 0, m_nBackBufferWidth, m_nBackBufferHeight);
+    SetViewPort(rect);
   }
-  else
+
+  // set camera to center of screen
+  CPoint camPoint = { m_nBackBufferWidth * 0.5f, m_nBackBufferHeight * 0.5f };
+  SetCameraPosition(camPoint, m_nBackBufferWidth, m_nBackBufferHeight);
+
+  CheckInterlasedStereoView();
+
+  if (bRestoreRTView)
+    m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, m_depthStencilView);
+
+  m_resizeInProgress = false;
+  m_bResizeRequred = false;
+
+  return true;
+}
+
+void CRenderSystemDX::CheckInterlasedStereoView(void)
+{
+  RENDER_STEREO_MODE stereoMode = g_graphicsContext.GetStereoMode();
+
+  if ( m_pRenderTargetViewRight 
+    && RENDER_STEREO_MODE_INTERLACED    != stereoMode
+    && RENDER_STEREO_MODE_CHECKERBOARD  != stereoMode
+    && RENDER_STEREO_MODE_HARDWAREBASED != stereoMode)
   {
-    m_nDeviceStatus = m_pD3DDevice->TestCooperativeLevel();
+    // release resources
+    SAFE_RELEASE(m_pRenderTargetViewRight);
+    SAFE_RELEASE(m_pShaderResourceViewRight);
+    SAFE_RELEASE(m_pTextureRight);
   }
 
-  if( FAILED( m_nDeviceStatus ) )
+  if ( !m_pRenderTargetViewRight
+    && ( RENDER_STEREO_MODE_INTERLACED   == stereoMode 
+      || RENDER_STEREO_MODE_CHECKERBOARD == stereoMode))
   {
-    // The device has been lost but cannot be reset at this time.
-    // Therefore, rendering is not possible and we'll have to return
-    // and try again at a later time.
-    if( m_nDeviceStatus == D3DERR_DEVICELOST )
+    // Create a second Render Target for the right eye buffer
+    HRESULT hr;
+    CD3D11_TEXTURE2D_DESC texDesc(DXGI_FORMAT_B8G8R8A8_UNORM, m_nBackBufferWidth, m_nBackBufferHeight, 1, 1,
+                                  D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
+    hr = m_pD3DDev->CreateTexture2D(&texDesc, NULL, &m_pTextureRight);
+    if (SUCCEEDED(hr))
     {
-      if (m_nDeviceStatus != oldStatus)
-        CLog::Log(LOGDEBUG, "D3DERR_DEVICELOST");
-      OnDeviceLost();
-      return false;
-    }
+      CD3D11_RENDER_TARGET_VIEW_DESC rtDesc(D3D11_RTV_DIMENSION_TEXTURE2D);
+      hr = m_pD3DDev->CreateRenderTargetView(m_pTextureRight, &rtDesc, &m_pRenderTargetViewRight);
 
-    // The device has been lost but it can be reset at this time.
-    if( m_nDeviceStatus == D3DERR_DEVICENOTRESET )
-    {
-      OnDeviceReset();
-      if( FAILED(m_nDeviceStatus ) )
+      if (SUCCEEDED(hr))
       {
-        CLog::Log(LOGINFO, "m_pD3DDevice->Reset failed");
-        return false;
+        CD3D11_SHADER_RESOURCE_VIEW_DESC srDesc(D3D11_SRV_DIMENSION_TEXTURE2D);
+        hr = m_pD3DDev->CreateShaderResourceView(m_pTextureRight, &srDesc, &m_pShaderResourceViewRight);
+
+        if (FAILED(hr))
+          CLog::Log(LOGERROR, "%s - Failed to create right view shader resource.", __FUNCTION__);
       }
+      else
+        CLog::Log(LOGERROR, "%s - Failed to create right view render target.", __FUNCTION__);
+    }
+
+    if (FAILED(hr))
+    {
+      SAFE_RELEASE(m_pShaderResourceViewRight);
+      SAFE_RELEASE(m_pRenderTargetViewRight);
+      SAFE_RELEASE(m_pTextureRight);
+
+      CLog::Log(LOGERROR, "%s - Failed to create right eye buffer.", __FUNCTION__);
+      g_graphicsContext.SetStereoMode(RENDER_STEREO_MODE_OFF); // try fallback to mono
     }
   }
+}
+
+bool CRenderSystemDX::CreateStates()
+{
+  if (!m_pD3DDev)
+    return false;
 
+  SAFE_RELEASE(m_depthStencilState);
+  SAFE_RELEASE(m_BlendEnableState);
+  SAFE_RELEASE(m_BlendDisableState);
+
+  // Initialize the description of the stencil state.
+  D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
+  ZeroMemory(&depthStencilDesc, sizeof(D3D11_DEPTH_STENCIL_DESC));
+
+  // Set up the description of the stencil state.
+  depthStencilDesc.DepthEnable = false;
+  depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+  depthStencilDesc.DepthFunc = D3D11_COMPARISON_NEVER;
+  depthStencilDesc.StencilEnable = false;
+  depthStencilDesc.StencilReadMask = 0xFF;
+  depthStencilDesc.StencilWriteMask = 0xFF;
+
+  // Stencil operations if pixel is front-facing.
+  depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+  depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
+  depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+  depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+
+  // Stencil operations if pixel is back-facing.
+  depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+  depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
+  depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+  depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+
+  // Create the depth stencil state.
+  HRESULT hr = m_pD3DDev->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState);
+  if(FAILED(hr))
+    return false;
+
+  // Set the depth stencil state.
+       m_pContext->OMSetDepthStencilState(m_depthStencilState, 0);
+
+  D3D11_RASTERIZER_DESC rasterizerState;
+  rasterizerState.CullMode = D3D11_CULL_BACK; 
+  rasterizerState.FillMode = D3D11_FILL_SOLID;// DEBUG - D3D11_FILL_WIREFRAME
+  rasterizerState.FrontCounterClockwise = false;
+  rasterizerState.DepthBias = 0;
+  rasterizerState.DepthBiasClamp = 0.0f;
+  rasterizerState.DepthClipEnable = true;
+  rasterizerState.SlopeScaledDepthBias = 0.0f;
+  rasterizerState.ScissorEnable = false;
+  rasterizerState.MultisampleEnable = false;
+  rasterizerState.AntialiasedLineEnable = false;
+
+  if (FAILED(m_pD3DDev->CreateRasterizerState(&rasterizerState, &m_RSScissorDisable)))
+    return false;
+
+  rasterizerState.ScissorEnable = true;
+  if (FAILED(m_pD3DDev->CreateRasterizerState(&rasterizerState, &m_RSScissorEnable)))
+    return false;
+
+  m_pContext->RSSetState(m_RSScissorDisable); // by default
+
+  D3D11_BLEND_DESC blendState = { 0 };
+  ZeroMemory(&blendState, sizeof(D3D11_BLEND_DESC));
+  blendState.RenderTarget[0].BlendEnable = true;
+  blendState.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; // D3D11_BLEND_SRC_ALPHA;
+  blendState.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; // D3D11_BLEND_INV_SRC_ALPHA;
+  blendState.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+  blendState.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
+  blendState.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
+  blendState.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+  blendState.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
+
+  m_pD3DDev->CreateBlendState(&blendState, &m_BlendEnableState);
+
+  blendState.RenderTarget[0].BlendEnable = false;
+  m_pD3DDev->CreateBlendState(&blendState, &m_BlendDisableState);
+
+  // by default
+  m_pContext->OMSetBlendState(m_BlendEnableState, nullptr, 0xFFFFFFFF);
+  m_BlendEnabled = true;
+
+  return true;
+}
+
+bool CRenderSystemDX::PresentRenderImpl(const CDirtyRegionList &dirty)
+{
   HRESULT hr;
 
-  if(FAILED(hr = m_pD3DDevice->BeginScene()))
+  if (!m_bRenderCreated)
+    return false;
+
+  if (m_nDeviceStatus != S_OK)
+    return false;
+
+  if ( m_stereoMode == RENDER_STEREO_MODE_INTERLACED
+    || m_stereoMode == RENDER_STEREO_MODE_CHECKERBOARD)
+  {
+    // all views prepared, let's merge them before present
+    m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, m_depthStencilView);
+    CRect destRect = { 0.0f, 0.0f, float(m_nBackBufferWidth), float(m_nBackBufferHeight) };
+    SHADER_METHOD method = RENDER_STEREO_MODE_INTERLACED == m_stereoMode
+                           ? SHADER_METHOD_RENDER_STEREO_INTERLACED_RIGHT
+                           : SHADER_METHOD_RENDER_STEREO_CHECKERBOARD_RIGHT;
+    SetAlphaBlendEnable(true);
+    CD3DTexture::DrawQuad(destRect, 0, 1, &m_pShaderResourceViewRight, NULL, method);
+    CD3DHelper::PSClearShaderResources(m_pContext);
+  }
+
+  FinishCommandList();
+
+  if (m_pSwapChain1) 
   {
-    CLog::Log(LOGERROR, "m_pD3DDevice->BeginScene() failed. %s", CRenderSystemDX::GetErrorDescription(hr).c_str());
-    // When XBMC caught an exception after BeginScene(), EndScene() may never been called
-    // and thus all following BeginScene() will fail too.
-    if(FAILED(hr = m_pD3DDevice->EndScene()))
-      CLog::Log(LOGERROR, "m_pD3DDevice->EndScene() failed. %s", CRenderSystemDX::GetErrorDescription(hr).c_str());
+    // will use optimized present with dirty regions.
+    DXGI_PRESENT_PARAMETERS presentParams = {};
+    presentParams.DirtyRectsCount = 0;
+    presentParams.pDirtyRects = NULL;
+    presentParams.pScrollRect = NULL;
+    hr = m_pSwapChain1->Present1((m_bVSync ? 1 : 0), 0, &presentParams);
+  }
+  else 
+    hr = m_pSwapChain->Present((m_bVSync ? 1 : 0), 0);
+
+  if (DXGI_ERROR_DEVICE_REMOVED == hr)
+  {
+    CLog::Log(LOGDEBUG, "%s - device removed", __FUNCTION__);
     return false;
   }
 
-  IDirect3DSurface9 *pBackBuffer;
-  if(m_pD3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer) != D3D_OK)
+  if (DXGI_ERROR_INVALID_CALL == hr)
+  {
+    m_bResizeRequred = true;
+    if (CreateWindowSizeDependentResources())
+      return true;
+  }
+
+  if (FAILED(hr))
+  {
+    CLog::Log(LOGDEBUG, "%s - Present failed. %s", __FUNCTION__, GetErrorDescription(hr).c_str());
     return false;
+  }
 
-  m_pD3DDevice->SetRenderTarget(0, pBackBuffer);
-  pBackBuffer->Release();
+  return true;
+}
+
+bool CRenderSystemDX::BeginRender()
+{
+  if (!m_bRenderCreated)
+    return false;
+
+  HRESULT oldStatus = m_nDeviceStatus;
+  if (m_pSwapChain1)
+  {
+    DXGI_PRESENT_PARAMETERS presentParams = {};
+    presentParams.DirtyRectsCount = 0;
+    presentParams.pDirtyRects = NULL;
+    presentParams.pScrollRect = NULL;
+    m_nDeviceStatus = m_pSwapChain1->Present1(0, DXGI_PRESENT_TEST, &presentParams);
+  }
+  else
+  {
+    m_nDeviceStatus = m_pSwapChain->Present(0, DXGI_PRESENT_TEST);
+  }
 
+  // handling of return values. 
+  switch (m_nDeviceStatus)
+  {
+  case DXGI_ERROR_DEVICE_REMOVED: // GPU has been physically removed from the system, or a driver upgrade occurred. 
+    CLog::Log(LOGERROR, "DXGI_ERROR_DEVICE_REMOVED");
+    m_needNewDevice = true;
+    break;
+  case DXGI_ERROR_DEVICE_RESET: // This is an run-time issue that should be investigated and fixed.
+    CLog::Log(LOGERROR, "DXGI_ERROR_DEVICE_RESET");
+    m_nDeviceStatus = DXGI_ERROR_DEVICE_REMOVED;
+    m_needNewDevice = true;
+    break;
+  case DXGI_ERROR_INVALID_CALL: // application provided invalid parameter data. Try to return after resize buffers
+    CLog::Log(LOGERROR, "DXGI_ERROR_INVALID_CALL");
+    m_bResizeRequred = true;
+    if (CreateWindowSizeDependentResources())
+      m_nDeviceStatus = S_OK;
+    break;
+  case DXGI_STATUS_OCCLUDED: // decide what we should do when windows content is not visible
+    // do not spam to log file
+    if (m_nDeviceStatus != oldStatus)
+      CLog::Log(LOGDEBUG, "DXGI_STATUS_OCCLUDED");
+    // Status OCCLUDED is not an error and not handled by FAILED macro, 
+    // but if it occurs we should not render anything, so just return false
+    return false;
+  }
+
+  if (FAILED(m_nDeviceStatus))
+  {
+    if (DXGI_ERROR_DEVICE_REMOVED == m_nDeviceStatus)
+    {
+      OnDeviceLost();
+    }
+    return false;
+  }
+
+  m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, m_depthStencilView);
   m_inScene = true;
+
   return true;
 }
 
@@ -719,42 +1213,47 @@ bool CRenderSystemDX::EndRender()
 
   if (!m_bRenderCreated)
     return false;
-
+  
   if(m_nDeviceStatus != S_OK)
     return false;
 
-  HRESULT hr = m_pD3DDevice->EndScene();
-  if(FAILED(hr))
-  {
-    CLog::Log(LOGERROR, "m_pD3DDevice->EndScene() failed. %s", CRenderSystemDX::GetErrorDescription(hr).c_str());
-    return false;
-  }
-
   return true;
 }
 
 bool CRenderSystemDX::ClearBuffers(color_t color)
 {
-  if (!m_bRenderCreated)
+  if (!m_bRenderCreated || m_resizeInProgress)
     return false;
 
-  if(m_stereoMode == RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN
-  || m_stereoMode == RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA
-  || m_stereoMode == RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE)
+  float fColor[4];
+  CD3DHelper::XMStoreColor(fColor, color);
+
+  // Unlike Direct3D 9, the full extent of the resource view is always cleared. Viewport and scissor settings are not applied.
+  if ( m_stereoMode != RENDER_STEREO_MODE_OFF
+    && m_stereoMode != RENDER_STEREO_MODE_MONO)
   {
-    // if stereo anaglyph, data was cleared when left view was rendererd
-    if(m_stereoView == RENDER_STEREO_VIEW_RIGHT)
-      return true;
-  }
+    // if stereo anaglyph/tab/sbs, data was cleared when left view was rendererd
+    if (m_stereoView == RENDER_STEREO_VIEW_RIGHT)
+    {
+      // execute command's queue
+      if ( m_stereoMode != RENDER_STEREO_MODE_SPLIT_HORIZONTAL
+        && m_stereoMode != RENDER_STEREO_MODE_SPLIT_VERTICAL)
+        FinishCommandList();
 
-  return SUCCEEDED(m_pD3DDevice->Clear(
-    0,
-    NULL,
-    D3DCLEAR_TARGET,
-    color,
-    1.0,
-    0 ) );
+      // for interlaced/checkerboard/hw clear right view
+      if (m_pRenderTargetViewRight)
+        m_pContext->ClearRenderTargetView(m_pRenderTargetViewRight, fColor);
 
+      // for hw stereo clear depth view also
+      if (m_stereoMode == RENDER_STEREO_MODE_HARDWAREBASED)
+        m_pContext->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0, 0);
+
+      return true;
+    }
+  }
+  m_pContext->ClearRenderTargetView(m_pRenderTargetView, fColor);
+  m_pContext->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0, 0);
   return true;
 }
 
@@ -765,7 +1264,7 @@ bool CRenderSystemDX::IsExtSupported(const char* extension)
 
 bool CRenderSystemDX::PresentRender(const CDirtyRegionList &dirty)
 {
-  if (!m_bRenderCreated)
+  if (!m_bRenderCreated || m_resizeInProgress)
     return false;
 
   bool result = PresentRenderImpl(dirty);
@@ -775,25 +1274,13 @@ bool CRenderSystemDX::PresentRender(const CDirtyRegionList &dirty)
 
 void CRenderSystemDX::SetVSync(bool enable)
 {
-  if (m_bVSync != enable)
-  {
-    bool inScene(m_inScene);
-    if (m_inScene)
-      EndRender();
-    m_bVSync = enable;
-    ResetRenderSystem(m_nBackBufferWidth, m_nBackBufferHeight, m_bFullScreenDevice, m_refreshRate);
-    if (inScene)
-      BeginRender();
-  }
+  m_bVSync = enable;
 }
 
 void CRenderSystemDX::CaptureStateBlock()
 {
   if (!m_bRenderCreated)
     return;
-
-  SAFE_RELEASE(m_stateBlock);
-  m_pD3DDevice->CreateStateBlock(D3DSBT_ALL, &m_stateBlock);
 }
 
 void CRenderSystemDX::ApplyStateBlock()
@@ -801,8 +1288,12 @@ void CRenderSystemDX::ApplyStateBlock()
   if (!m_bRenderCreated)
     return;
 
-  if (m_stateBlock)
-    m_stateBlock->Apply();
+  m_pContext->RSSetState(m_ScissorsEnabled ? m_RSScissorEnable : m_RSScissorDisable);
+  m_pContext->OMSetDepthStencilState(m_depthStencilState, 0);
+  float factors[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+  m_pContext->OMSetBlendState(m_BlendEnabled ? m_BlendEnableState : m_BlendDisableState, factors, 0xFFFFFFFF);
+
+  m_pGUIShader->ApplyStateBlock();
 }
 
 void CRenderSystemDX::SetCameraPosition(const CPoint &camera, int screenWidth, int screenHeight)
@@ -814,45 +1305,31 @@ void CRenderSystemDX::SetCameraPosition(const CPoint &camera, int screenWidth, i
   float w = m_viewPort.Width*0.5f;
   float h = m_viewPort.Height*0.5f;
 
-  CPoint offset = camera - CPoint(screenWidth*0.5f, screenHeight*0.5f);
+  XMFLOAT2 offset = XMFLOAT2(camera.x - screenWidth*0.5f, camera.y - screenHeight*0.5f);
 
-  // world view.  Until this is moved onto the GPU (via a vertex shader for instance), we set it to the identity
-  // here.
-  D3DXMATRIX mtxWorld;
-  D3DXMatrixIdentity(&mtxWorld);
-  m_pD3DDevice->SetTransform(D3DTS_WORLD, &mtxWorld);
+  // world view.  Until this is moved onto the GPU (via a vertex shader for instance), we set it to the identity here.
+  m_pGUIShader->SetWorld(XMMatrixIdentity());
 
+  // Initialize the view matrix
   // camera view.  Multiply the Y coord by -1 then translate so that everything is relative to the camera
   // position.
-  D3DXMATRIX flipY, translate, mtxView;
-  D3DXMatrixScaling(&flipY, 1.0f, -1.0f, 1.0f);
-  D3DXMatrixTranslation(&translate, -(w + offset.x), -(h + offset.y), 2*h);
-  D3DXMatrixMultiply(&mtxView, &translate, &flipY);
-  m_pD3DDevice->SetTransform(D3DTS_VIEW, &mtxView);
+  XMMATRIX flipY, translate;
+  flipY = XMMatrixScaling(1.0, -1.0f, 1.0f);
+  translate = XMMatrixTranslation(-(w + offset.x), -(h + offset.y), 2 * h);
+  m_pGUIShader->SetView(XMMatrixMultiply(translate, flipY));
 
   // projection onto screen space
-  D3DXMATRIX mtxProjection;
-  D3DXMatrixPerspectiveOffCenterLH(&mtxProjection, (-w - offset.x)*0.5f, (w - offset.x)*0.5f, (-h + offset.y)*0.5f, (h + offset.y)*0.5f, h, 100*h);
-  m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &mtxProjection);
-
-  m_world = mtxWorld;
-  m_view = mtxView;
-  m_projection = mtxProjection;
+  m_pGUIShader->SetProjection(XMMatrixPerspectiveOffCenterLH((-w - offset.x)*0.5f, (w - offset.x)*0.5f, (-h + offset.y)*0.5f, (h + offset.y)*0.5f, h, 100 * h));
 }
 
 void CRenderSystemDX::Project(float &x, float &y, float &z)
 {
-  D3DXVECTOR3 vScreenCoord;
-  D3DXVECTOR3 vLocation(x, y, z);
-
-  D3DXVec3Project(&vScreenCoord, &vLocation, &m_viewPort, &m_projection, &m_view, &m_world);
-  x = vScreenCoord.x;
-  y = vScreenCoord.y;
-  z = 0;
+  m_pGUIShader->Project(x, y, z);
 }
 
 bool CRenderSystemDX::TestRender()
 {
+  /*
   static unsigned int lastTime = 0;
   static float delta = 0;
 
@@ -913,7 +1390,7 @@ bool CRenderSystemDX::TestRender()
   m_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
 
   pVB->Release();
-
+  */
   return true;
 }
 
@@ -934,10 +1411,10 @@ void CRenderSystemDX::GetViewPort(CRect& viewPort)
   if (!m_bRenderCreated)
     return;
 
-  viewPort.x1 = (float)m_viewPort.X;
-  viewPort.y1 = (float)m_viewPort.Y;
-  viewPort.x2 = (float)m_viewPort.X + m_viewPort.Width;
-  viewPort.y2 = (float)m_viewPort.Y + m_viewPort.Height;
+  viewPort.x1 = m_viewPort.TopLeftX;
+  viewPort.y1 = m_viewPort.TopLeftY;
+  viewPort.x2 = m_viewPort.TopLeftX + m_viewPort.Width;
+  viewPort.y2 = m_viewPort.TopLeftY + m_viewPort.Height;
 }
 
 void CRenderSystemDX::SetViewPort(CRect& viewPort)
@@ -945,13 +1422,15 @@ void CRenderSystemDX::SetViewPort(CRect& viewPort)
   if (!m_bRenderCreated)
     return;
 
-  m_viewPort.MinZ   = 0.0f;
-  m_viewPort.MaxZ   = 1.0f;
-  m_viewPort.X      = (DWORD)viewPort.x1;
-  m_viewPort.Y      = (DWORD)viewPort.y1;
-  m_viewPort.Width  = (DWORD)(viewPort.x2 - viewPort.x1);
-  m_viewPort.Height = (DWORD)(viewPort.y2 - viewPort.y1);
-  m_pD3DDevice->SetViewport(&m_viewPort);
+  m_viewPort.MinDepth   = 0.0f;
+  m_viewPort.MaxDepth   = 1.0f;
+  m_viewPort.TopLeftX   = viewPort.x1;
+  m_viewPort.TopLeftY   = viewPort.y1;
+  m_viewPort.Width      = viewPort.x2 - viewPort.x1;
+  m_viewPort.Height     = viewPort.y2 - viewPort.y1;
+
+  m_pContext->RSSetViewports(1, &m_viewPort);
+  m_pGUIShader->SetViewPort(m_viewPort);
 }
 
 void CRenderSystemDX::RestoreViewPort()
@@ -959,7 +1438,29 @@ void CRenderSystemDX::RestoreViewPort()
   if (!m_bRenderCreated)
     return;
 
-  m_pD3DDevice->SetViewport(&m_viewPort);
+  m_pContext->RSSetViewports(1, &m_viewPort);
+  m_pGUIShader->SetViewPort(m_viewPort);
+}
+
+bool CRenderSystemDX::ScissorsCanEffectClipping()
+{
+  return m_pGUIShader != NULL && m_pGUIShader->HardwareClipIsPossible(); 
+}
+
+CRect CRenderSystemDX::ClipRectToScissorRect(const CRect &rect)
+{
+  if (!m_bRenderCreated)
+    return CRect();
+
+  float xFactor = m_pGUIShader->GetClipXFactor();
+  float xOffset = m_pGUIShader->GetClipXOffset();
+  float yFactor = m_pGUIShader->GetClipYFactor();
+  float yOffset = m_pGUIShader->GetClipYOffset();
+
+  return CRect(rect.x1 * xFactor + xOffset,
+               rect.y1 * yFactor + yOffset,
+               rect.x2 * xFactor + xOffset,
+               rect.y2 * yFactor + yOffset);
 }
 
 void CRenderSystemDX::SetScissors(const CRect& rect)
@@ -967,13 +1468,15 @@ void CRenderSystemDX::SetScissors(const CRect& rect)
   if (!m_bRenderCreated)
     return;
 
-  RECT scissor;
+  D3D11_RECT scissor;
   scissor.left   = MathUtils::round_int(rect.x1);
   scissor.top    = MathUtils::round_int(rect.y1);
   scissor.right  = MathUtils::round_int(rect.x2);
   scissor.bottom = MathUtils::round_int(rect.y2);
-  m_pD3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
-  m_pD3DDevice->SetScissorRect(&scissor);
+
+  m_pContext->RSSetState(m_RSScissorEnable);
+  m_ScissorsEnabled = true;
+  m_pContext->RSSetScissorRects(1, &scissor);
 }
 
 void CRenderSystemDX::ResetScissors()
@@ -981,13 +1484,15 @@ void CRenderSystemDX::ResetScissors()
   if (!m_bRenderCreated)
     return;
 
-  RECT scissor;
+  D3D11_RECT scissor;
   scissor.left = 0;
   scissor.top = 0;
   scissor.right = m_nBackBufferWidth;
   scissor.bottom = m_nBackBufferHeight;
-  m_pD3DDevice->SetScissorRect(&scissor);
-  m_pD3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+
+  m_pContext->RSSetScissorRects(1, &scissor);
+  m_pContext->RSSetState(m_RSScissorDisable);
+  m_ScissorsEnabled = false;
 }
 
 void CRenderSystemDX::Register(ID3DResource *resource)
@@ -999,52 +1504,99 @@ void CRenderSystemDX::Register(ID3DResource *resource)
 void CRenderSystemDX::Unregister(ID3DResource* resource)
 {
   CSingleLock lock(m_resourceSection);
-  vector<ID3DResource*>::iterator i = find(m_resources.begin(), m_resources.end(), resource);
+  std::vector<ID3DResource*>::iterator i = find(m_resources.begin(), m_resources.end(), resource);
   if (i != m_resources.end())
     m_resources.erase(i);
 }
 
 std::string CRenderSystemDX::GetErrorDescription(HRESULT hr)
 {
-  return StringUtils::Format("%X - %s (%s)", hr, DXGetErrorString(hr), DXGetErrorDescription(hr));
+  WCHAR buff[1024];
+  DXGetErrorDescription(hr, buff, 1024);
+  std::wstring error(DXGetErrorString(hr));
+  std::wstring descr(buff);
+  return StringUtils::Format("%X - %ls (%ls)", hr, error.c_str(), descr.c_str());
 }
 
 void CRenderSystemDX::SetStereoMode(RENDER_STEREO_MODE mode, RENDER_STEREO_VIEW view)
 {
   CRenderSystemBase::SetStereoMode(mode, view);
 
-  m_pD3DDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN);
+  if (!m_bRenderCreated)
+    return;
+
+  UINT writeMask = D3D11_COLOR_WRITE_ENABLE_ALL;
   if(m_stereoMode == RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN)
   {
     if(m_stereoView == RENDER_STEREO_VIEW_LEFT)
-      m_pD3DDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED );
+      writeMask = D3D11_COLOR_WRITE_ENABLE_RED;
     else if(m_stereoView == RENDER_STEREO_VIEW_RIGHT)
-      m_pD3DDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN );
+      writeMask = D3D11_COLOR_WRITE_ENABLE_BLUE | D3D11_COLOR_WRITE_ENABLE_GREEN;
   }
   if(m_stereoMode == RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA)
   {
     if(m_stereoView == RENDER_STEREO_VIEW_LEFT)
-      m_pD3DDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN );
+      writeMask = D3D11_COLOR_WRITE_ENABLE_GREEN;
     else if(m_stereoView == RENDER_STEREO_VIEW_RIGHT)
-      m_pD3DDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_RED );
+      writeMask = D3D11_COLOR_WRITE_ENABLE_BLUE | D3D11_COLOR_WRITE_ENABLE_RED;
   }
-  if(m_stereoMode == RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE)
+  if (m_stereoMode == RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE)
   {
-    if(m_stereoView == RENDER_STEREO_VIEW_LEFT)
-      m_pD3DDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN);
-    else if(m_stereoView == RENDER_STEREO_VIEW_RIGHT)
-      m_pD3DDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE);
+    if (m_stereoView == RENDER_STEREO_VIEW_LEFT)
+      writeMask = D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN;
+    else if (m_stereoView == RENDER_STEREO_VIEW_RIGHT)
+      writeMask = D3D11_COLOR_WRITE_ENABLE_BLUE;
+  }
+  if ( RENDER_STEREO_MODE_INTERLACED    == m_stereoMode
+    || RENDER_STEREO_MODE_CHECKERBOARD  == m_stereoMode
+    || RENDER_STEREO_MODE_HARDWAREBASED == m_stereoMode)
+  {
+    if (m_stereoView == RENDER_STEREO_VIEW_RIGHT)
+    {
+      // render right eye view to right render target
+      m_pContext->OMSetRenderTargets(1, &m_pRenderTargetViewRight, m_depthStencilView);
+    }
+  }
+
+  D3D11_BLEND_DESC desc;
+  m_BlendEnableState->GetDesc(&desc);
+  // update blend state
+  if (desc.RenderTarget[0].RenderTargetWriteMask != writeMask)
+  {
+    SAFE_RELEASE(m_BlendDisableState);
+    SAFE_RELEASE(m_BlendEnableState);
+
+    desc.RenderTarget[0].RenderTargetWriteMask = writeMask;
+    m_pD3DDev->CreateBlendState(&desc, &m_BlendEnableState);
+
+    desc.RenderTarget[0].BlendEnable = false;
+    m_pD3DDev->CreateBlendState(&desc, &m_BlendDisableState);
+
+    float blendFactors[] = { 0.0f, 0.0f, 0.0f, 0.0f };
+    m_pContext->OMSetBlendState(m_BlendEnabled ? m_BlendEnableState : m_BlendDisableState, blendFactors, 0xFFFFFFFF);
   }
 }
 
 bool CRenderSystemDX::SupportsStereo(RENDER_STEREO_MODE mode) const
 {
-  switch(mode)
+  bool isHWStereoSupport = false;
+  IDXGIFactory2* dxgiFactory2 = NULL;
+  if (SUCCEEDED(m_dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2))))
+  {
+    isHWStereoSupport = dxgiFactory2 && dxgiFactory2->IsWindowedStereoEnabled();
+  }
+  SAFE_RELEASE(dxgiFactory2);
+
+  switch (mode)
   {
     case RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN:
     case RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA:
     case RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE:
+    case RENDER_STEREO_MODE_INTERLACED:
+    case RENDER_STEREO_MODE_CHECKERBOARD:
       return true;
+    case RENDER_STEREO_MODE_HARDWAREBASED:
+      return isHWStereoSupport;
     default:
       return CRenderSystemBase::SupportsStereo(mode);
   }
@@ -1052,15 +1604,54 @@ bool CRenderSystemDX::SupportsStereo(RENDER_STEREO_MODE mode) const
 
 void CRenderSystemDX::FlushGPU()
 {
-  IDirect3DQuery9* pEvent = NULL;
+  FinishCommandList();
+  m_pImdContext->Flush();
+}
+
+bool CRenderSystemDX::InitGUIShader()
+{
+  if (!m_pD3DDev)
+    return false;
 
-  m_pD3DDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pEvent);
-  if (pEvent != NULL)
+  SAFE_DELETE(m_pGUIShader);
+  m_pGUIShader = new CGUIShaderDX();
+  if (!m_pGUIShader->Initialize())
   {
-    pEvent->Issue(D3DISSUE_END);
-    while (S_FALSE == pEvent->GetData(NULL, 0, D3DGETDATA_FLUSH))
-      Sleep(1);
+    CLog::Log(LOGERROR, __FUNCTION__ " - Failed to initialize GUI shader.");
+    return false;
   }
+
+  m_pGUIShader->ApplyStateBlock();
+
+  return true;
+}
+
+void CRenderSystemDX::SetAlphaBlendEnable(bool enable)
+{
+  if (!m_bRenderCreated)
+    return;
+
+  float blendFactors[] = { 0.0f, 0.0f, 0.0f, 0.0f };
+  m_pContext->OMSetBlendState(enable ? m_BlendEnableState : m_BlendDisableState, 0, 0xFFFFFFFF);
+  m_BlendEnabled = enable;
+}
+
+void CRenderSystemDX::FinishCommandList(bool bExecute /*= true*/)
+{
+  if (m_pImdContext == m_pContext)
+    return;
+
+  ID3D11CommandList* pCommandList = NULL;
+  if (FAILED(m_pContext->FinishCommandList(true, &pCommandList)))
+  {
+    CLog::Log(LOGERROR, "%s - Failed to finish command queue.", __FUNCTION__);
+    return;
+  }
+
+  if (bExecute)
+    m_pImdContext->ExecuteCommandList(pCommandList, false);
+
+  SAFE_RELEASE(pCommandList);
 }
 
 #endif
index 0697bed..5d97dde 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <vector>
 #include "rendering/RenderSystem.h"
+#include "guilib/GUIShaderDX.h"
 #include "threads/CriticalSection.h"
 
 enum PCI_Vendors
@@ -54,8 +55,7 @@ public:
   virtual bool PresentRender(const CDirtyRegionList &dirty);
   virtual bool ClearBuffers(color_t color);
   virtual bool IsExtSupported(const char* extension);
-  virtual bool IsSurfaceFormatOk(D3DFORMAT surfFormat, DWORD usage);
-  virtual bool IsTextureFormatOk(D3DFORMAT texFormat, DWORD usage);
+  virtual bool IsFormatSupport(DXGI_FORMAT format, unsigned int usage);
 
   virtual void SetVSync(bool vsync);
 
@@ -63,6 +63,8 @@ public:
   virtual void GetViewPort(CRect& viewPort);
   virtual void RestoreViewPort();
 
+  virtual CRect ClipRectToScissorRect(const CRect &rect);
+  virtual bool ScissorsCanEffectClipping();
   virtual void SetScissors(const CRect &rect);
   virtual void ResetScissors();
 
@@ -77,18 +79,24 @@ public:
   virtual bool SupportsStereo(RENDER_STEREO_MODE mode) const;
   virtual bool TestRender();
 
+  void         GetDisplayMode(DXGI_MODE_DESC *mode, bool useCached = false);
+  IDXGIOutput* GetCurrentOutput(void) { return m_pOutput; }
+
   virtual void Project(float &x, float &y, float &z);
 
+  void FinishCommandList(bool bExecute = true);
   void FlushGPU();
 
-  LPDIRECT3DDEVICE9 Get3DDevice() { return m_pD3DDevice; }
-  int GetBackbufferCount() const { return m_D3DPP.BackBufferCount; }
-
-  bool    UseD3D9Ex()       { return m_useD3D9Ex; }
-  DWORD   DefaultD3DUsage() { return m_defaultD3DUsage; }
-  D3DPOOL DefaultD3DPool()  { return m_defaultD3DPool; }
-  D3DADAPTER_IDENTIFIER9 GetAIdentifier() { return m_AIdentifier; }
-  bool    Interlaced()      { return m_interlaced; }
+  ID3D11Device*           Get3D11Device()      { return m_pD3DDev; }
+  ID3D11DeviceContext*    Get3D11Context()     { return m_pContext; }
+  ID3D11DeviceContext*    GetImmediateContext(){ return m_pImdContext; }
+  CGUIShaderDX*           GetGUIShader()       { return m_pGUIShader; }
+  unsigned                GetFeatureLevel()    { return m_featureLevel; }
+  D3D11_USAGE             DefaultD3DUsage()    { return m_defaultD3DUsage; }
+  DXGI_ADAPTER_DESC       GetAIdentifier()     { return m_adapterDesc; }
+  bool                    Interlaced()         { return m_interlaced; }
+  int                     GetBackbufferCount() const { return 2; }
+  void                    SetAlphaBlendEnable(bool enable);
 
   /*!
    \brief Register as a dependent of the DirectX Render System
@@ -121,22 +129,23 @@ protected:
   void SetDeviceWnd(HWND wnd) { m_hDeviceWnd = wnd; }
   void SetMonitor(HMONITOR monitor);
   void SetRenderParams(unsigned int width, unsigned int height, bool fullScreen, float refreshRate);
-  void BuildPresentParameters();
-  virtual void UpdateMonitor() {};
-  BOOL IsDepthFormatOk(D3DFORMAT DepthFormat, D3DFORMAT RenderTargetFormat);
+  bool CreateWindowSizeDependentResources();
+  bool CreateStates();
+  bool InitGUIShader();
   void OnMove();
+  void OnResize(unsigned int width, unsigned int height);
+  void SetFullScreenInternal();
+  void GetClosestDisplayModeToCurrent(IDXGIOutput* output, DXGI_MODE_DESC* outCurrentDisplayMode, bool useCached = false);
+  void CheckInterlasedStereoView(void);
 
-  LPDIRECT3D9                 m_pD3D;
+  virtual void UpdateMonitor() {};
 
   // our adapter could change as we go
   bool                        m_needNewDevice;
-  unsigned int                m_adapter;
-  LPDIRECT3DDEVICE9           m_pD3DDevice;
+  bool                        m_needNewViews;
+  bool                        m_resizeInProgress;
   unsigned int                m_screenHeight;
 
-  D3DDEVTYPE                  m_devType;
-  D3DPRESENT_PARAMETERS       m_D3DPP;
-  D3DDISPLAYMODEEX            m_D3DDMEX;
   HWND                        m_hFocusWnd;
   HWND                        m_hDeviceWnd;
   unsigned int                m_nBackBufferWidth;
@@ -145,23 +154,53 @@ protected:
   float                       m_refreshRate;
   bool                        m_interlaced;
   HRESULT                     m_nDeviceStatus;
-  IDirect3DStateBlock9*       m_stateBlock;
   int64_t                     m_systemFreq;
-  bool                        m_useD3D9Ex;
-  DWORD                       m_defaultD3DUsage;
-  D3DPOOL                     m_defaultD3DPool;
+  D3D11_USAGE                 m_defaultD3DUsage;
   bool                        m_useWindowedDX;
-  D3DADAPTER_IDENTIFIER9      m_AIdentifier;
 
   CCriticalSection            m_resourceSection;
   std::vector<ID3DResource*>  m_resources;
 
   bool                        m_inScene; ///< True if we're in a BeginScene()/EndScene() block
 
-  D3DVIEWPORT9                m_viewPort;
-  D3DXMATRIX                  m_projection;
-  D3DXMATRIX                  m_view;
-  D3DXMATRIX                  m_world;
+  D3D_DRIVER_TYPE             m_driverType;
+  D3D_FEATURE_LEVEL           m_featureLevel;
+  IDXGIFactory1*              m_dxgiFactory;
+  ID3D11Device*               m_pD3DDev;
+  IDXGIAdapter1*              m_adapter;
+  int                         m_adapterIndex;
+  IDXGIOutput*                m_pOutput;
+  ID3D11DeviceContext*        m_pContext;
+  ID3D11DeviceContext*        m_pImdContext;
+
+  IDXGISwapChain*             m_pSwapChain;
+  IDXGISwapChain1*            m_pSwapChain1;
+  ID3D11RenderTargetView*     m_pRenderTargetView;
+  ID3D11DepthStencilState*    m_depthStencilState;
+  ID3D11DepthStencilView*     m_depthStencilView;
+  D3D11_VIEWPORT              m_viewPort; 
+
+  CGUIShaderDX*               m_pGUIShader;
+  ID3D11BlendState*           m_BlendEnableState;
+  ID3D11BlendState*           m_BlendDisableState;
+  bool                        m_BlendEnabled;
+  ID3D11RasterizerState*      m_RSScissorDisable;
+  ID3D11RasterizerState*      m_RSScissorEnable;
+  bool                        m_ScissorsEnabled;
+  DXGI_ADAPTER_DESC           m_adapterDesc;
+
+  // stereo interlaced/checkerboard intermediate target
+  ID3D11Texture2D*            m_pTextureRight;
+  ID3D11RenderTargetView*     m_pRenderTargetViewRight;
+  ID3D11ShaderResourceView*   m_pShaderResourceViewRight;
+  bool                        m_bResizeRequred;
+  bool                        m_bHWStereoEnabled;
+
+  // improve get current mode
+  DXGI_MODE_DESC              m_cachedMode;
+#ifdef _DEBUG
+  ID3D11Debug*                m_d3dDebug = NULL;
+#endif
 };
 
 #endif