Jump to content

  • Log In with Google      Sign In   
  • Create Account


GetRenderTargetData - does it block?


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
13 replies to this topic

#1 Omroth   Members   -  Reputation: 122

Like
0Likes
Like

Posted 24 May 2010 - 02:02 AM

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;

Sponsor:

#2 Evil Steve   Members   -  Reputation: 1955

Like
0Likes
Like

Posted 24 May 2010 - 02:32 AM

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.

Steve Macpherson
Senior programmer, Firebrand Games


#3 Omroth   Members   -  Reputation: 122

Like
0Likes
Like

Posted 24 May 2010 - 02:40 AM

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

#4 Evil Steve   Members   -  Reputation: 1955

Like
0Likes
Like

Posted 24 May 2010 - 02:57 AM

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.

#5 Omroth   Members   -  Reputation: 122

Like
0Likes
Like

Posted 24 May 2010 - 03:11 AM

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

#6 Evil Steve   Members   -  Reputation: 1955

Like
0Likes
Like

Posted 24 May 2010 - 04:15 AM

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.

#7 crowley9   Members   -  Reputation: 226

Like
0Likes
Like

Posted 24 May 2010 - 06:47 AM

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.

#8 Omroth   Members   -  Reputation: 122

Like
0Likes
Like

Posted 24 May 2010 - 07:56 AM

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

#9 Omroth   Members   -  Reputation: 122

Like
0Likes
Like

Posted 24 May 2010 - 07:59 AM

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

I suppose I should try a driver update as well.

#10 Rubicon   Members   -  Reputation: 296

Like
0Likes
Like

Posted 24 May 2010 - 08:35 PM

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.

#11 Omroth   Members   -  Reputation: 122

Like
0Likes
Like

Posted 24 May 2010 - 08:46 PM

You misunderstand - I /thought/ I was getting the finished frame, as was implied above, by my current method. What extra do I need to do to "lock" it?

#12 Nik02   Crossbones+   -  Reputation: 2648

Like
0Likes
Like

Posted 24 May 2010 - 08:55 PM

When you use the "do not wait" flag with the lock, you say that you don't care if the rendering is finished or not - just give the data that is in the buffer this instance. Try removing the flag.

I believe that in most GPUs, the surface-to-surface copy is implemented as a simple render operation (though probably bypassing most of the geometry setup needed in "ordinary" rendering). A diagonal tear might simply be an artifact of this process.

#13 Omroth   Members   -  Reputation: 122

Like
0Likes
Like

Posted 24 May 2010 - 10:31 PM

I've tried removing the flags but still get the tearing - am I locking the right thing at the right place? Do I need to "lock" the backbuffer as well?

Thanks for all the help guys,
Ian

#14 JohnnyCode   Members   -  Reputation: 192

Like
0Likes
Like

Posted 25 May 2010 - 09:55 AM

Guys I googled this
Quote:

"
When I try to play Nocturne it gives me the error message:

Unable to Lock Front Buffer

File: wddvmem.cpp
Line: 838

I'm running Vista, but I've changed the GameTap compatibility properties to XP. I've tried everything that works with other games (i.e. BlloodRayne) such as Run as Administrator, Run in 256 Color, Run in 600x480 etc. If anyone has any other suggestions I'm game.
"


If front buffer is lockable , then, after call to Present(), Front buffer is lockable with delay of 0. If present() blocks of course. You should be able to access it for reading.




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