title: Copying render target data to D3DPOOL_MANAGED?
body: <p>I'm <a href="http://hge.relishgames.com" rel="nofollow">using an engine</a> which utilizes DirectX9.<br/></p>
  
  <p><strong>It creates it's render targets using:</strong></p>
  
  <pre><code>D3DXCreateTexture(
      pD3DDevice, width, height, 1, 
      D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, 
      D3DPOOL_DEFAULT, &amp;pRT
  )
  </code></pre>
  
  <p><br/>
  <strong>And all other textures are created like so:</strong></p>
  
  <pre><code>D3DXCreateTexture(
      pD3DDevice, width, height,
      1, 0, D3DFMT_A8R8G8B8,
      D3DPOOL_MANAGED, &amp;pTex
  )
  </code></pre>
  
  <p>It is worth noting that the backbuffer is also <code>D3DFMT_X8R8G8B8</code> so I am unsure why textures are created differently... but I suppose <em>"if it ain't broke, don't fix it,"</em> right? All textures appear to load/render just fine.
  For more details on how this engine operates, <a href="https://github.com/kvakvs/hge/blob/master/src/core/graphics.cpp" rel="nofollow">here is it's main graphics module's code</a>.<br/>
  <em>(mostly note the <code>Target_Create</code> and <code>Texture_Create</code> methods)...</em><br/><br/></p>
  
  <p><strong>HOWEVER</strong>, I've had a ton of trouble trying to stick with these rules while trying to convert a render target texture into a regular texture. The engine has no built-in functionality for this, and render targets are treated as separate objects from textures... And in turn, this limits my ability to actually <em>USE</em> anything which requires a render target (ie, pixel shaders, etc). The end result is that I need to find a way to copy this render target data into a texture created as above, which the engine could use without any conflict.</p>
  
  <p><em><strong>I have tried something like the following:</em></strong></p>
  
  <pre><code>inline PVOID LockedBits(LPDIRECT3DSURFACE9 surface, UINT w, UINT h, INT* size)
  {
      D3DLOCKED_RECT lr;
      RECT rc = {0, 0, w, h};
      surface-&gt;LockRect(&amp;lr, &amp;rc, 0);
      if(size) *size = (w*h) * 4;
      return lr.pBits;
  }
  inline PVOID LockedBits(LPDIRECT3DTEXTURE9 texture, UINT w, UINT h, INT* size)
  {
      D3DLOCKED_RECT lr;
      RECT rc = {0, 0, w, h};
      texture-&gt;LockRect(0, &amp;lr, &amp;rc, 0);
      if(size) *size = (w*h) * 4;
      return lr.pBits;
  }
  
  LPDIRECT3DTEXTURE9 CloneTextureFromTarget(LPDIRECT3DDEVICE9 device, LPDIRECT3DTEXTURE9 target, UINT w, UINT h)
  {
      D3DDISPLAYMODE dm;
      device-&gt;GetDisplayMode(0, &amp;dm);
  
      // Create source and destination surfaces and copy rendertarget
      LPDIRECT3DSURFACE9 dstSurf = NULL, srcSurf = NULL;
      device-&gt;CreateOffscreenPlainSurface(w, h, dm.Format, D3DPOOL_SYSTEMMEM, &amp;dstSurf, NULL);
      target-&gt;GetSurfaceLevel(0, &amp;srcSurf);
      device-&gt;GetRenderTargetData(srcSurf, dstSurf);
      SafeRelease(&amp;srcSurf);
  
      // Create destination texture
      LPDIRECT3DTEXTURE9 dstTexture = NULL;
      D3DXCreateTexture(device, w, h, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &amp;dstTexture);
  
      // Get bits for destination surface and texture
      INT dwSrc, dwDst;
      PVOID pBitsSrc = LockedBits(dstSurf, w, h, &amp;dwSrc);
      PVOID pBitsDst = LockedBits(dstTexture, w, h, &amp;dwDst);
  
      // Copy bits from surface to texture
      RtlCopyMemory(pBitsSrc, pBitsDst, dwSrc);
      dstTexture-&gt;UnlockRect(0);
      dstSurf-&gt;UnlockRect();
      SafeRelease(&amp;dstSurf);
  
      /* Just to double-check if it worked... */
      D3DXSaveTextureToFileA("C:\\outSrc.png", D3DXIFF_PNG, target, NULL);
      D3DXSaveTextureToFileA("C:\\outDst.png", D3DXIFF_PNG, dstTexture, NULL);
  
      // Return the result
      return dstTexture;
  }
  </code></pre>
  
  <p>The result of this code is that both textures are properly saved to disk and come out as expected, but refuse to properly render...</p>
  
  <p>Am I doing something wrong?
  What's the best way to achieve a perfect copy of this data into a new texture created with <code>D3DFMT_A8R8G8B8</code> and <code>D3DPOOL_MANAGED</code>?</p>