Fast DirectX Screen Capture

Started by
5 comments, last by Hodgman 12 years, 11 months ago
Hello,I have to do a application wich take a screenshoot and send it by net with a UDP MULTICAST protocol.
The problem is that the screen shoot is too slow.I have created a texture with D3DUSAGE_RENDERTARGET flag,after i have get the surface 0 in the texture and I have putted it in the directx device as render target 0.
Anybody knows a faster method?Thanks.Perhaps is too slow why I´m using d3dxSaveTextureToFileInMemory with a JPG???

Thanks!!!!
Advertisement
Please be more precise, your app render what ? how much time does the rendering frame cost (fps) ?
Like you describe it, your application seems to do nothing apart dumping the framebuffer ?
i don't think the rendering into the rendertarget is slow, rather the JPG compression can be slow if you do it once per frame on a full framebuffer ...

If you want to know this run a basic free profiler like very sleepy, it's free and reveal you what time is spent in wich functions.
You should be able to just grab the back buffer.


if (ui.DumpBackbuffer)
{
LPDIRECT3DSURFACE9 psurf;

// Get the present params from the swap chain
IDirect3DSurface9* pBackBuffer = NULL;
hr = pDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
if( SUCCEEDED(hr) )
{

hr = D3DXSaveSurfaceToFile(thumbNail.c_str(), D3DXIFF_JPG, pBackBuffer, NULL, NULL);

SAFE_RELEASE( pBackBuffer );
}
}



If saving to disk is too slow, you can try to save to memory first, then save the surfaces.
It's been a while since I've done this, but IIRC the fastest way I found was to create two render targets, and change which one I'm using each frame. I'd then read from the other render-target each frame using GetRenderTargetData.
i.e. Frame #1 -- Render to A, Get data for B. Frame #2 -- Render to B, Get data for A.

Also, if you use the GPU to compress the data before downloading it to the CPU, the transfer will be much faster.
Hodgman why is faster render on a buffer and extract info from the another buffer?????The code is secuential.You must to render first in a buffer and the "render time" is the same in A that B.You after must get data and the "get data" time is the same in A that B.Perhaps the solution is change the buffers in one thread and read in another thread???Please,Can you write me some code or explain me with more detail?

Thanks!!!

Hodgman why is faster render on a buffer and extract info from the another buffer?????The code is secuential.You must to render first in a buffer and the "render time" is the same in A that B.You after must get data and the "get data" time is the same in A that B.Perhaps the solution is change the buffers in one thread and read in another thread???Please,Can you write me some code or explain me with more detail?

Thanks!!!


The GPU runs in parallel with the CPU. So by putting instructions in the right order you can gain performance.Think of it as two threads but one runs on the CPU and the other on your graphics card.
Yeah, it's a type of double-buffering, which is used a lot in threaded systems to hide latency.

When you issue a command to DirectX, this command gets put into a queue, which the GPU will execute at a later point in time.

e.g.
If you write 5 commands, like this:Draw...//#1
Draw...//#2
Draw...//#3
Draw...//#4
GetRenderTargetData...//#5
Then when the CPU reaches command #5, the GPU might only be processing command #1 still!
If this happens, it means the CPU has to sit around waiting for the GPU to catch up before it can download the render target.

If you instead try to download the render target that was used on the previous frame, there's more chance that the GPU has actually finished rendering to that target already.

e.g. In this example the CPU finishes trying to modify target 'a' at #4, but doesn't ask for the data until #10, which gives the GPU much more time to finish it's work.SetRenderTarget( a )//#1
Draw...//#2
Draw...//#3
Draw...//#4
GetRenderTargetData( b )//#5

SetRenderTarget( b )//#6
Draw...//#7
Draw...//#8
Draw...//#9
GetRenderTargetData( a )//#10

This topic is closed to new replies.

Advertisement