GetRenderTargetData - does it block?

Started by
12 comments, last by JohnnyCode 13 years, 11 months ago
Hey guys. I have some code I'm using here to grab the back buffer onto a surface in main memory. My question is: does this block? Ie, will the surface in main memory be ready when this has finished executing? Thanks, Ian D3DDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &bBuffer ); // Figure the size we're snagging. D3DSURFACE_DESC desc; bBuffer->GetDesc(&desc); HRESULT hr = D3DDevice->CreateOffscreenPlainSurface(desc.Width,desc.Height,desc.Format,D3DPOOL_SYSTEMMEM,&mBuffer,NULL); D3DDevice->GetRenderTargetData(bBuffer , mBuffer); bBuffer->Release(); if (lastBuffer) { lastBuffer->UnlockRect(); lastBuffer->Release(); } // TODO: Investigate alternatives to D3DLOCK_DONOTWAIT D3DLOCKED_RECT pLockedRect; hr = mBuffer->LockRect(&pLockedRect,NULL, D3DLOCK_DONOTWAIT); lastBuffer = mBuffer;
Advertisement
Quote:Original post by Omroth
My question is: does this block? Ie, will the surface in main memory be ready when this has finished executing?
Yes, it'll block - GetRenderTargetData() will finish rendering anything queued up and then copy the contents of the backbuffer to mBuffer.
Thanks EvilSteve.

I've heard a lot about the inefficiencies of getRenderTargetData requiring DX to finish rendering all of the stuff "queed up". If I'm not worried about screen output, would it make sense to render to a series of buffers, and only call getRenderTargetData on each buffer once it's finished rendering? Would that have an appreciable speed increase?

Thanks,
Ian
You could double buffer the results, I.e. render to two render targets in turn, which could help, but would introduce a frame of lag.

Why do you need to get the render target data in the first place? There may be a better way to do things.
I'm able to deal with lag of up to a second really, I just need to be able to get frames from the card to main memory as close to 25 frames a second as possible. I also have no requirement for the graphics card to output anything via VGA at all.

What I'm basically doing is using DirectX/the 3d card to create a video stream, which needs to go via main memory to a separate card for further processing before being output.

Can you think of any techniques I can use to speed this all up?

Cheers,
Ian
I think you'll probably get the best performance out of using GetRenderTargetData() with a double-buffered system. Anything else will involve locking a default pool resource in non-readonly mode, which is usually a killer for performance.
DX10 has better support for ths sort of thng (staging buffers, and DO_NOT_WAIT locks), which will likely give you better performance. If using DX10 is an option for you, this is the way to go.
Thanks again guys.

I'm getting some weird output from this now. The frames I'm getting sent down have a tear in them, a diagonal tear where the top left "corner" seems to be from the previous frame, so I'm assuming that the backbuffer is being written to as GetRenderTargetData is doing the copy.

This goes against what I was expected - do you have any suggestions how I can diagnose this further?

Thanks,
Ian
Fyi, this is on a Radeon 5850 running Catalyst drivers 2009.0925.1707.28889.

I suppose I should try a driver update as well.
You can either lock and get a perfect frame, or read it "right the hell now" and you'll get something that isn't quite finished. Not sure what the 3rd option is that you're looking for tbh - this is a logical problem, not a rendering specific thing.

Best advice has been given - use a locking method and double-buffer it to keep the throughput speed up.
------------------------------Great Little War Game

This topic is closed to new replies.

Advertisement