• Advertisement

Archived

This topic is now archived and is closed to further replies.

GetRenderTargetData() seems blocking the CPU

This topic is 5024 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
Advertisement
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 -

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 -

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 -

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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 -

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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%!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

  • Advertisement