Sign in to follow this  

d3d10 convert render to texture to image format (e.g. bmp)

This topic is 2961 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

Hi all, I am trying to save each rendered frame (which is a Render to Texture) into an image format so I can do some CPU image processing. The only thing I found while googling was a d3d9 device method d3dDevice->GetRenderTargetData() which it seems you can get the rgba bits from that. I'm not sure if this is the best way but it is also d3d9 and I am looking for a solution in d3d10. Thanks for any help!

Share this post


Link to post
Share on other sites
There's a D3DX function for saving images, don't know if RTs create problems with that function.

D3DX10SaveTextureToFile

http://msdn.microsoft.com/en-us/library/ee416738(VS.85).aspx

You might want to give it a try, but I suppose it's going to slow down your rendering process a lot!

Share this post


Link to post
Share on other sites
Thanks undead!

Hmm, you were right about performance. I even tried the D3DX10SaveTextureToMemory() and the performance hit was almost just as bad. If this is the only way, then I guess it will have to do.

Share this post


Link to post
Share on other sites
So it turns out this is way too slow for me. Can anyone explain why this is so slow so maybe I can figure out a way to speed it up?

I'm guessing it is so slow because copying (1024x768 pixels)(8*3 bpp) is a ton of memory to copy every frame. Also, maybe the render target resides on the video card's memory so it has to be copied to system memory too?

But how does programs like fraps still work without this bad of a performance hit? (I know fraps performance hit is bad, but it isn't as bad as what I'm getting).

Thanks :D

Share this post


Link to post
Share on other sites
Firstly if speed is what you need I'd suggest doing the image processing on the GPU, they can generally do it much quicker than the CPU. What effect are you trying to achieve?

If you really need to read the data on the CPU I'd suggest alternating between two render targets. Render to one while you copy the data out of the other. That will hopefully mean the GPU isn't going to be idle so much.

You may also be able to get more performance by avoiding D3DX and doing all the steps yourself. For example if you're requesting R8G8B8 when the buffer format is X8R8G8B8 then D3DX will be doing some format conversion for you.

Other than that profile it (try both a CPU and GPU profilers) to find out where the slowness is coming from.

Share this post


Link to post
Share on other sites
Quote:
Original post by link3978
So it turns out this is way too slow for me. Can anyone explain why this is so slow so maybe I can figure out a way to speed it up?

I'm guessing it is so slow because copying (1024x768 pixels)(8*3 bpp) is a ton of memory to copy every frame. Also, maybe the render target resides on the video card's memory so it has to be copied to system memory too?

But how does programs like fraps still work without this bad of a performance hit? (I know fraps performance hit is bad, but it isn't as bad as what I'm getting).

Thanks :D

Fraps can't sustain more than 30fps, at least with my pc, even if the scenes are simple (running at 250/300fps without grabbing).

I suppose one of the problems of the method I suggested is the continous allocation/deallocation. If you read back the texture you can allocate space once and fill it every frame. This might help.

Another thing which could help is to save raw files, after all you have a 24/32 bit framebuffer, no need to write appropriate headers. Save raw data then convert them later with an external application.

Another bad thing is the HDD latency. I'm pretty sure fraps is faster rendering videos than single frames. They don't need to create/close many files. They have their own video codec and add it to a file... I think it's an uncompressed (or poorly compressed) one because the files it generates are HUGE.

My suggestion is the following:
- create a file ONCE (like "myvideo.rawvideo") you can include a custom header (screen res and format)
- allocate memory for the current frame only ONCE
* for each frame
- retrieve data from texture -> write to your frame in memory
- add the raw frame to "myvideo.rawvideo"
* end of frame
- deallocate memory
- close the file

Then you can write a simple program reading "myvideo.rawvideo" and exporting each frame.

For reading back texture data in D3D9 I used LockRect().
I suppose you can do something similar in D3D10 (sorry I'm not a D3D10 programming expert) with Map(). Just be sure you set the correct CPU access flags.

Share this post


Link to post
Share on other sites

This topic is 2961 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this