What's the most efficient way to read video memory back into system memory?
Hi,
I've got an app now that sends the vb etc, off to the graphics pipeline renders to a surface in video memory and then uses GetRenderTargetData( VideoMemoryTargetSurface, SystemMemorySurface ) to get it back into system memory. I can't help but feel there must be a much better non blocking way to do this. One that frees up the cpu to do other things and does some form of async callback when the rendering is finished/texture is back in memory etc. Any info you've got on my different options would be much appreciated.
Thanks,
Andy
No, there's no non-blocking call you can make in D3D9. You can keep a secondary thread going if you'd like, as long as it doesn't make any D3D calls.
The main problem with this is that due to the asynchronous nature of graphics hardware, the render target data won't be there until some time after you've made the actual Draw calls. Remember that the CPU can be up to 2 frames ahead of the GPU...and if you make a call to GetRenderTargetData you'll have to wait for the GPU to finish those frames before you can access the data.
What you can do to make this faster is to use a few different render targets, and switch which one you render to each frame. Then instead of reading the data from the render target you used for the current frame, you use one from 2 frames ago. It introduces some lag in your calculations, but it will prevent you from stalling the pipeline.
The main problem with this is that due to the asynchronous nature of graphics hardware, the render target data won't be there until some time after you've made the actual Draw calls. Remember that the CPU can be up to 2 frames ahead of the GPU...and if you make a call to GetRenderTargetData you'll have to wait for the GPU to finish those frames before you can access the data.
What you can do to make this faster is to use a few different render targets, and switch which one you render to each frame. Then instead of reading the data from the render target you used for the current frame, you use one from 2 frames ago. It introduces some lag in your calculations, but it will prevent you from stalling the pipeline.
Thanks Matt,
You mention there is no way in D3D9 is there some way in DX10 or DX11 or would I have to go native on NVIDIA or something? If you happen to have any info that's great but I'll be researching this anyway, I really want to find the fastest way to process the most data possible.
I'd thought of the secondary thread and just leaving that to stall on the D3D calls I assume that's an efficient thread wait but I hadn't had the idea of using multiple buffers so as not to block on the pipeline, so thanks for that : )
Cheers,
Andy
You mention there is no way in D3D9 is there some way in DX10 or DX11 or would I have to go native on NVIDIA or something? If you happen to have any info that's great but I'll be researching this anyway, I really want to find the fastest way to process the most data possible.
I'd thought of the secondary thread and just leaving that to stall on the D3D calls I assume that's an efficient thread wait but I hadn't had the idea of using multiple buffers so as not to block on the pipeline, so thanks for that : )
Cheers,
Andy
A short update: multiple buffers won't work as well, at least not within D3D9. I tried that approach to avoid/minimize stalling, but it turned out that the current driver implementations (I only tested ATI yet) do NOT check if the render target is still being used. So you get the GPU/CPU sync anyways, even if all rendering to that single buffer has been completed already.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement