Skip to main content
GameDev.net gamedev.net
🔒 Locked

GetRenderTargetData() seems blocking the CPU

Started by softimage Apr 15, 2004 at 10:42 AM 9 replies 4.7k views
Original Post
softimage
softimage
I am using GetRenderTargetData() to downloading the rendertarget texture to system memory. It''s fast enough, but the downloading of a 720*480 texture at 30 times/second brings a CPU usage of 40% on my Pentium4 3G. It is 7% when there''s no downloading. So maybe this function hangs the cpu. How can I make it non-locking?
Muhammad Haggag
Muhammad Haggag
It''s locking because the CPU has to wait for the data you requested to be downloaded to system memory (otherwise, when you would access the surface bits, you''d access garbage).

There''s no way around it, sadly, except waiting for PCI Express.

Muhammad Haggag,
Optimize
Bitwise account: MHaggag -

softimage
softimage
quote:
Original post by Coder
There''s no way around it, sadly, except waiting for PCI Express.



Well, I have to say that I also tested it on an RV380 factory sample, which is using PCI Express.
And the downloading speed just goes up to 2 times!
Maybe now the board and the driver is not mature.

GetRenderTargetData() in RV380 still waits until the rendering is completed.
So I''m wondering whether directx can let the cpu do other job and inform the cpu to download the texture when the rendering is over.
Muhammad Haggag
Muhammad Haggag
quote:
Original post by softimage
GetRenderTargetData() in RV380 still waits until the rendering is completed.
So I''m wondering whether directx can let the cpu do other job and inform the cpu to download the texture when the rendering is over.

Well, asyncrhonous notification is the purpose of D3D9 queries.


Muhammad Haggag,
Optimize
Bitwise account: MHaggag -

softimage
softimage
I thought the GetRenderTargetData() takes some cpu time to
wait for the completion of rendering.
So I tried adding a Sleep(100) before it.
But the time spent on this line is still exactly the same.
So maybe the downloading itself, without waiting, wastes 0.0224 second.

Now I''m seeking whether directx has some function like the
completion routine in I/O file reading.
Muhammad Haggag
Muhammad Haggag
quote:
Original post by softimage
But the time spent on this line is still exactly the same.
So maybe the downloading itself, without waiting, wastes 0.0224 second.

Yes, the downloading is very slow. Rendering itself shouldn''t be that slow at all. Games like UT2k3 lock the back-buffer each frame to force the rendering to be finished before the next-frame, and they still achieve high frame-rates.

Muhammad Haggag,
Optimize
Bitwise account: MHaggag -

softimage
softimage
A bit strange that after I added more computation into my shader program,
the GetRenderTargetData() took more CPU.
The CPU usage rose from 20% to 30%.
So this function must be waiting for the completion of rendering.

If I add Sleep(100) before it, the CPU usage can come down,
but the time spent on this function is still the same?!

How can I avoid this useless waiting?
Muhammad Haggag
Muhammad Haggag
quote:
Original post by softimage
How can I avoid this useless waiting?

The only way I know of is to avoid calling GerRenderTargetData

Is there no other way for you to do what you want to do?

Muhammad Haggag,
Optimize
Bitwise account: MHaggag -

jollyjeffers
jollyjeffers
quote:
So this function must be waiting for the completion of rendering.
strikes me as an obvious fact really... Remember that the GPU''s are designed to be highly parallel where possible. Your ''DrawPrimitive'' call will return to your game BEFORE the primitive is fully rasterized to the render target. The GPU will often backup render calls etc...

With that in mind, for your GetRenderTargetData() call to be serviced all calls waiting in the queue before it MUST be completed. Hence the wait.

I''d guess the ONLY way to get around this is maybe to multi-thread the AI/Physics of your game, and allow said components to be scheduled some execution time while the 3D pipeline is stalling.

hth
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
softimage
softimage
Sorry that I made a mistake.
After adding Sleep(100), the cpu usage really came down,
and the time spent on GetRenderTargetData() was also reduced.
Besides, it''s faster if I put the downloading after the Present().
I tested different sleep time, and found that the time of
GetRenderTargetData is at least 0.0089.
Without sleep, it may be 0.0224.

So I think this function will first wait for the completion of rendering, then download.
Sleep can leave the time of waiting to CPU, but not the downloading.
So the downloading itself costs 0.0089 second.
Well, it''s fast enough.
But the cpu usage is too high, 27%.
Without downloading, it''s only 9%!
SoulSpectre
SoulSpectre
A solutioncould be to pad the spaces between your capture and rendering with cpu only coding eg:


programloop(){
some cpu only stuff;
capture;
some more cpu only stuff;
render;
}


Also you will need to handle the first capture since it will occur before any rendering. Simple enough.

This way be padding out the space you can give the GPU some free time to get the rendering out of the way before capture and vise versa and you can make use of that time with the cpu coding of your app.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.