Hook to a D3D11 process without Present and grab Texture2D

1.3k views Asked by At

I have some D3D11 process I am hooking to capture frames. If the process calls Present(), there is no problem to capture frame, but... In some cases it has no visible window and no Present() method is called, but frame is really rendered. I can hook up Draw(), ExecudeCommandList() (and other) methods. Actually, there is no Present() called so I have no access to SwapChain's backbuffer. I suppose there is no SwapChain created when app is running w/o window.

When I hook Draw() or ExecuteCommandList(), I have access to D3D11Device and D3D11DeviceContext only.

Using API monitor I captured some information on D3D11 calls at the end of each frame:

enter image description here

Does anyone have any idea how can I get the resulting frame? My purpose is to get frame into D3D11Texture2D.

Thanks!

UPD:

I found that this method can be helpful for me: ID3D11DeviceContext::ResolveSubresource, but I can't handle hooking it. It is amortized (in main app I am trying to grab frame).

Part of VTable log:

[56]    5E225520    (CContext::TID3D11DeviceContext_GetResourceMinLOD_<1>)
[57]    5E1B95C0    (CContext::TID3D11DeviceContext_ResolveSubresource_Amortized<1>)
[58]    5E21DEC0    (CContext::TID3D11DeviceContext_ExecuteCommandList_<1>)

Thanks 2!

1

There are 1 answers

0
Svyatoslav Krasnitskiy On BEST ANSWER

If you have an access to ID3D11DeviceContext in any hooked D3D11 method, you can try calling OMGetRenderTargets method and get the resource from it:

ID3D11RenderTargetView *view = NULL;
pContext->OMGetRenderTargets(1, &view, NULL);
ID3D11Resource *pSourceResource = NULL;
view->GetResource(&pSourceResource);

Then you can save it to file as a Texture2D:

D3DX11SaveTextureToFile(pContext, pSourceResource, D3DX11_IFF_BMP, "image.bmp");

Or you can save Texture2D buffer on Output-Merger (OM) stage.