I have a DirectX rendering that works perfectly when I render to the screen:
var DxDevice = D3D.D3DDevice.CreateDeviceAndSwapChain(host.Handle);
...
var DxFinalRenderTexture = DxDevice.SwapChain.GetBuffer<D3D.Texture2D>(0);
var DxFinalRenderTarget = DxDevice.CreateRenderTargetView(DxFinalRenderTexture);
DxDevice.OM.RenderTargets = new D3D.OutputMergerRenderTargets(new D3D.RenderTargetView[] { DxFinalRenderTarget }, null);
DxTechnique.GetPassByIndex(0).Apply();
DxDevice.Draw(4, 0);
DxDevice.SwapChain.Present(0, GX.PresentOptions.None);
(input layout and vertex buffers are omitted here because, as I said, the rendering works as expected to the screen).
When I change it slightly to use a different render target rather than the screen:
var description = new D3D.Texture2DDescription() {
Width = 1024,
Height = 1024,
ArraySize = 1,
BindingOptions = D3D.BindingOptions.RenderTarget | D3D.BindingOptions.ShaderResource,
CpuAccessOptions = D3D.CpuAccessOptions.None,
Format = DX.Graphics.Format.B8G8R8A8UNorm,
MipLevels = 1,
MiscellaneousResourceOptions = D3D.MiscellaneousResourceOptions.None,
SampleDescription = new DX.Graphics.SampleDescription(1, 0),
Usage = D3D.Usage.Default
};
var DxFinalRenderTexture = DxDevice.CreateTexture2D(description);
var description2 = new D3D.RenderTargetViewDescription() {
Format = description.Format,
ViewDimension = D3D.RenderTargetViewDimension.Texture2D,
Texture2D = new D3D.Texture2DRenderTargetView() { MipSlice = 0 }
};
var DxFinalRenderTarget = DxDevice.CreateRenderTargetView(DxFinalRenderTexture, description2);
and finally save the texture by duly copying it to a staging resource and mapping the latter:
private WriteableBitmap GetTexture(D3D.Texture2D texture) {
var description = new D3D.Texture2DDescription() {
Width = 1024,
Height = 1024,
ArraySize = 1,
BindingOptions = D3D.BindingOptions.None,
CpuAccessOptions = D3D.CpuAccessOptions.Read,
Format = DX.Graphics.Format.B8G8R8A8UNorm,
MipLevels = 1,
MiscellaneousResourceOptions = D3D.MiscellaneousResourceOptions.None,
SampleDescription = new DX.Graphics.SampleDescription(1, 0),
Usage = D3D.Usage.Staging
};
var texture2 = DxDevice.CreateTexture2D(description);
DxDevice.CopyResource(texture2, texture);
var texmap = texture2.Map(0, D3D.Map.Read, D3D.MapOptions.None);
var bitmap = new WriteableBitmap(1024, 1024, 96, 96, PixelFormats.Pbgra32, null);
bitmap.Lock();
bitmap.WritePixels(new Int32Rect(0, 0, 1024, 1024), texmap.Data, 1024 * 1024 * 4, 1024 * 4);
bitmap.Unlock();
texture2.Unmap(0);
return bitmap;
}
the resulting bitmap will be completely empty. There are no errors either in compilation or during the run, just the emptiness.
It might also be worth noting that I don't need repeatedly rendered frames, just a single bitmap created, so there are no performance issues involved. I'd be happy to do away with the screen rendering completely and render to a final bitmap that I can use later.