I have IDirect3DSurface9, default pool, YUV format. How can I efficiently get bitmap bits from it? At the moment I:
device->CreateRenderTarget(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &render_target, NULL)
device->StretchRect(videomem_surf, NULL, render_target_, NULL, D3DTEXF_NONE)
device->CreateOffscreenPlainSurface(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &sysmem_offscreen_surf, NULL)
device->GetRenderTargetData(render_target, sysmem_offscreen_surface)
this looks a bit of overhead, because of so many copying: from original surface to render target, then to offscreen surface, then to compatible bitmap, and then finally to my buffer. How can this be improved?
thanks
Well as interjay points out ... you are nearly doing things the "correct" way.
The obvious improvements are to call CreateRenderTarget and CreateOffscreenPlainSurface once and then re-use them multiple times. The fastest way of getting the bits back out would be to directly LockRect the surface.
Furthermore if you are needing to do this in real-time on something like video it would probably be better to set up an array of surfaces (both types). You can then load multiple YUV frames on to the CreateRenderTarget'd surface and then once you have filled the array then copy the first to the OffscreenPlainSurface and lock it.
This way you will allow more of the commands to be pipelined and stop you calling lock and FORCING a synchronisation of the pipeline (ie the surface you are locking HAS to be ready before proceeding which causes a pipeline sync).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With