Jump to content

  • Log In with Google      Sign In   
  • Create Account

Copying render target data to D3DPOOL_MANAGED?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
No replies to this topic

#1 Rectangle   Members   -  Reputation: 161

Like
0Likes
Like

Posted 30 April 2013 - 02:35 PM

The engine I am using creates render targets like so:

D3DXCreateTexture(pD3DDevice, width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pRT)

 

It also creates textures with:

D3DXCreateTexture(pD3DDevice, width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTex)

 

Is it possible to copy the render target data to one of these D3DPOOL_MANAGED textures? In DX8, we used CopyRects to get the job done. In DX9, it appears to have been replaced with UpdateTexture, UpdateSurface, GetRenderTargetData, LockRect, etc. But since the formats slightly differ, as well as the pools, most attempts I have made at using these functions have failed at one point or another with either E_FAIL or D3DERR_INVALIDCALL.
 
I did eventually get this to work via:
inline PVOID LockedBits(LPDIRECT3DSURFACE9 surface, UINT w, UINT h, INT* size)
{
    D3DLOCKED_RECT lr;
    RECT rc = {0, 0, w, h};
    surface->LockRect(&lr, &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->LockRect(0, &lr, &rc, 0);
    if(size) *size = (w*h) * 4;
    return lr.pBits;
}

LPDIRECT3DTEXTURE9 CloneTextureFromTarget(LPDIRECT3DDEVICE9 device, LPDIRECT3DTEXTURE9 target, UINT w, UINT h)
{
    D3DDISPLAYMODE dm;
    device->GetDisplayMode(0, &dm);

    // Create source and destination surfaces and copy rendertarget
    LPDIRECT3DSURFACE9 dstSurf = NULL, srcSurf = NULL;
    device->CreateOffscreenPlainSurface(w, h, dm.Format, D3DPOOL_SYSTEMMEM, &dstSurf, NULL);
    target->GetSurfaceLevel(0, &srcSurf);
    device->GetRenderTargetData(srcSurf, dstSurf);
    SafeRelease(&srcSurf);

    // Create destination texture
    LPDIRECT3DTEXTURE9 dstTexture = NULL;
    D3DXCreateTexture(device, w, h, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &dstTexture);

    // Get bits for destination surface and texture
    INT dwSrc, dwDst;
    PVOID pBitsSrc = LockedBits(dstSurf, w, h, &dwSrc);
    PVOID pBitsDst = LockedBits(dstTexture, w, h, &dwDst);

    // Copy bits from surface to texture
    RtlCopyMemory(pBitsSrc, pBitsDst, dwSrc);
    dstTexture->UnlockRect(0);
    dstSurf->UnlockRect();
    SafeRelease(&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;
}

 

...But even though both textures save to disk and appear correct, the returned texture refuses to render (or only renders black pixels).
And yet, all other textures created by the engine in this manner seem to render just fine. So what am I doing wrong?
And what would be the most efficient way of getting this to work?

Edited by Rectangle, 30 April 2013 - 02:36 PM.


Sponsor:



Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS