Hello,
I'm a newbie (as ever) with Direct3D and I'd like to know what is the most efficient way to do the very simple thing I want to do. I have a bunch of pictures in system memory that all get updated 60 times per second, and after every update I want to get each of them into a different IDirect3DSurface9 that has the USAGE_RENDERTARGET flag set (for use with WPF). I am using SharpDX but I can easily translate from native C++ if you're more comfortable using that.
I have a working sample but I'm not happy with the performance. It starts choking with about 8 640x480 renderers, while I can get 50 renderers using a software approach. It doesn't seem right that a hardware approach would be slower. :S
So far here's what I've done (using SharpDX, I hope d3d afficionados will understand easily):
Device creation (where s_hwnd is the window handle of the application):
s_d3d = new Direct3DEx();
var d3dpp = new PresentParameters
{
BackBufferCount = 1,
BackBufferHeight = 1,
BackBufferWidth = 1,
BackBufferFormat = Format.Unknown,
DeviceWindowHandle = s_hwnd,
SwapEffect = SwapEffect.Discard,
Windowed = true
};
s_device = new DeviceEx(s_d3d, 0, DeviceType.Hardware, s_hwnd,
CreateFlags.HardwareVertexProcessing | CreateFlags.FpuPreserve | CreateFlags.Multithreaded,
new PresentParameters[] { d3dpp }, new DisplayModeEx[] {});
Surface.CreateRenderTargetEx(s_device, 640, 480, Format.X8R8G8B8, MultisampleType.None, 0, true, Usage.None);
At render time we copy the data (a byte array) to the renderer's surface; this happens for each renderer.
public void Render(byte[] data)
{
// wpf code
m_d3dImage.Lock();
// d3d code
var textureData = m_surface.LockRectangle(LockFlags.None);
Marshal.Copy(data, 0, textureData.DataPointer, data.Length);
m_surface.UnlockRectangle();
// wpf code
m_d3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, m_surface.NativePointer);
m_d3dImage.AddDirtyRect(new Int32Rect(0, 0, 640, 480));
m_d3dImage.Unlock();
}