title: How to render YUV data by using DirectX11 or DirectX12
body: <p>I have a C++ dll project where YUV data has been processed by using directX9 in an IDirect3DSurface9. Then this surface has been passed to the WPF side by a callback function to render it from WPF side by using D3DImage. But rendering FPS is very slow, near around or below 30 FPS. But we are expecting 50~60 FPS.</p>
  <pre><code>  ComPtr&lt;IDirect3D9Ex&gt;           m_pD3D9Ex; 
    ComPtr&lt;IDirect3DDevice9Ex&gt;     m_pDeviceEx; 
    ComPtr&lt;IDirect3DSurface9&gt;      m_pDirect3DSurfaceRender;
    ComPtr&lt;IDirect3DSurface9&gt;      m_pTargetSurface; 
    ComPtr&lt;IDirect3DTexture9&gt;      m_pTexture; 
    ComPtr&lt;IDirect3DVertexBuffer9&gt; m_pVertexBuffer; 
    ComPtr&lt;IDirect3DVertexShader9&gt; m_pVertexShader; 
    ComPtr&lt;ID3DXConstantTable&gt;     m_pVertexConstantTable;    
    ComPtr&lt;ID3DXConstantTable&gt;     m_pPixelConstantTable;
    ComPtr&lt;IDirect3DPixelShader9&gt;  m_pPixelShader; 
    
      
    RESULT MyDirect3D9::Render(BYTE* pYplane, BYTE* pUplane, BYTE* pVplane)
    {
       HRESULT lRet;
    
       //Necessary Checkings for buffer and other stuff
    
       // fill buffer
      if(m_pDirect3DSurfaceRender == NULL)
          return -1;
      D3DLOCKED_RECT d3d_rect;
      lRet=m_pDirect3DSurfaceRender-&gt;LockRect(&amp;d3d_rect,NULL,D3DLOCK_DONOTWAIT);
      if(FAILED(lRet))
          return -1;
    
      int newHeight  = m_videoHeight;
       int newWidth  = m_videoWidth;
    
       BYTE* pict = (BYTE*)d3drect.pBits;
       BYTE* Y = pY;
       BYTE* V = pV;
       BYTE* U = pU;
    
      //Copy D3DFMT_YV12 Data
      for (int y = 0 ; y &lt; newHeight ; y++)
       {
           memcpy(pict, Y, newWidth);
           pict += d3drect.Pitch;
           Y += newWidth;
       }
       for (int y = 0 ; y &lt; newHeight &gt;&gt; 1; y++)
       {
           memcpy(pict, V, newWidth &gt;&gt; 1);
           pict += d3drect.Pitch &gt;&gt; 1;
           V += newWidth &gt;&gt; 1;
       }
       for (int y = 0 ; y &lt; newHeight &gt;&gt; 1; y++)
       {
           memcpy(pict, U, newWidth &gt;&gt; 1);
           pict += d3drect.Pitch &gt;&gt; 1;
           U += newWidth &gt;&gt; 1;
       }  
    
      lRet=m_pDirect3DSurfaceRender-&gt;UnlockRect();
      if(FAILED(lRet))
          return -1;
      
       // create scene
      if (m_pDirect3DDevice == NULL)
          return -1;
      
      //All kinds of HR check has been performed. For code simplicity, detail code has not been mensioned.
       lRet = m_pDirect3DDevice-&gt;Clear(D3DADAPTER_DEFAULT, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
       lRet = m_pDirect3DDevice-&gt;BeginScene();
       lRet = m_pDirect3DDevice-&gt;SetFVF(D3DFVF_CUSTOMVERTEX);
       lRet = m_pDirect3DDevice-&gt;SetVertexShader(m_pVertexShader);
       lRet = m_pDirect3DDevice-&gt;SetPixelShader(m_pPixelShader);
       lRet = m_pDirect3DDevice-&gt;SetStreamSource(0, m_pVertexBuffer, 0, sizeof(VERTEX));
       lRet = m_pDirect3DDevice-&gt;SetTexture(0, m_pTexture);
       lRet = m_pDirect3DDevice-&gt;DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
      
       m_overlays.Draw();
       m_pDirect3DDevice-&gt;EndScene();
      
      //IDirect3DSurface9 * pBackBuffer = NULL;
      //m_pDirect3DDevice-&gt;GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&amp;pBackBuffer);
      //m_pDirect3DDevice-&gt;StretchRect(m_pDirect3DSurfaceRender,NULL,pBackBuffer,&amp;m_rtViewport,D3DTEXF_LINEAR);
      //m_pDirect3DDevice-&gt;EndScene();
      //m_pDirect3DDevice-&gt;Present( NULL, NULL, NULL, NULL );
      //pBackBuffer-&gt;Release();
      
      // present 
       lRet = m_pDirect3DDevice-&gt;ColorFill(m_pTargetSurface, NULL, D3DCOLOR_ARGB(0xFF, 0, 0, 0));
      lRet = m_pDirect3DDevice-&gt;StretchRect(m_pDirect3DSurfaceRender, NULL, m_pTargetSurface, NULL, D3DTEXF_LINEAR);
      lRet = m_pDirect3DDevice-&gt;Present( NULL, NULL, NULL, NULL );
       
      return lRet;
     }
    
  </code></pre>
  <p>Here below is the WPF side D3DImage render:</p>
  <pre><code>     //WPF side code
   public void OnRender(IntPtr pSurface) 
   {
       if (d3dimg.IsFrontBufferAvailable)
       {
           if (pSurface != IntPtr.Zero)
           {
               PrintFPS();
  
               d3dimg.Lock();
               d3dimg.SetBackBuffer(D3DResourceType.IDirect3DSurface9, pSurface);
               d3dimg.AddDirtyRect(new Int32Rect(0, 0, d3dimg.PixelWidth, d3dimg.PixelHeight));
               d3dimg.Unlock();
           }
       }
   }
  </code></pre>
  <p><a href="https://software.intel.com/content/www/us/en/develop/blogs/siggraph-2014-directx-12-on-intel.html" rel="nofollow noreferrer">Intel showed up how using DirectX 12 can all to a 70% improvement in performance as well as using 50% less power</a>.</p>
  <p>Now I want to process/render YUV data by using DirectX11/DirectX12. The rendering process seems very different from DirectX9 to DirectX11/DirectX12.</p>
  <p>Any kind of help will be appreciated. Thanks in advance.</p>
  <p>Update:
  Be more concrete: To perform DirectX9 render we follow the below procedure:</p>
  <ol>
  <li><p>Copy YUV buffer to a byte pointer using IDirect3DSurface9</p>
  </li>
  <li><p>Create IDirect3DDevice9 device such as m_pDirect3DDevice.</p>
  </li>
  <li><p>Perform m_pDirect3DDevice-&gt;Clear</p>
  </li>
  <li><p>m_pDirect3DDevice-&gt;BeginScene()</p>
  </li>
  <li><p>Get back buffer: m_pDirect3DDevice-&gt;GetBackBuffer(...)</p>
  </li>
  <li><p>Then StretchRect to the predefined surface. m_pDirect3DDevice-&gt;StretchRect(....)</p>
  </li>
  <li><p>Finally perform EndScene &amp; Present(...)</p>
  </li>
  </ol>
  <p>I want to know the basic rendering procedure for DirectX11 or DirectX12</p>
  <p>I have checked out below link below but still unable to find any fruitful observation for YUV data rendering.</p>
  <p><a href="https://github.com/Microsoft/WPFDXInterop/blob/master/samples/D3D11Image/WpfD3D11Interop/MainWindow.xaml.cs" rel="nofollow noreferrer">WPFDXInterop</a> , <a href="https://github.com/microsoft/WPFDXInterop" rel="nofollow noreferrer">WPF DirectX Extensions</a>, <a href="https://github.com/GPUOpen-LibrariesAndSDKs/HelloD3D12/" rel="nofollow noreferrer">GPUOpen Libraries &amp; SDKs</a></p>