I am trying to read a texture from the back buffer of a swap chain in DirectX12 using SharpDX, but I can't figure it out. I get an "The parameter is incorrect" exception when trying to map the texture resource, and I can't get anymore debug info than that.
The code:
TextureCopyLocation destLocation;
TextureCopyLocation srcLocation;
using (var backBuffer = swapChain.GetBackBuffer<Resource>(0))
{
var display = new Display
{
Height = backBuffer.Description.Height,
Width = (int)backBuffer.Description.Width
};
var description = swapChain.Description;
var description1 = new SwapChainDescription1
{
BufferCount = description.BufferCount,
Flags = description.Flags,
SampleDescription = description.SampleDescription,
SwapEffect = description.SwapEffect,
Usage = description.Usage,
Format = description.ModeDescription.Format,
Width = description.ModeDescription.Width,
Height = description.ModeDescription.Height,
AlphaMode = AlphaMode.Ignore,
Scaling = Scaling.None,
Stereo = false
};
}
SwapChain1 swapChain;
using (var factory = new Factory4())
{
_device = new Device(null, FeatureLevel.Level_12_0);
_commandQueue = device.CreateCommandQueue(new CommandQueueDescription(CommandListType.Direct));
using (var form = new RenderForm())
{
swapChain = new SwapChain1(factory, queue, form.Handle, ref description1);
}
destLocation = new TextureCopyLocation(_screenTexture, 0);
srcLocation = new TextureCopyLocation(backBuffer, 0);
}
var textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, display.Width, display.Height);
_screenTexture = _device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);
var commandAllocator = _device.CreateCommandAllocator(CommandListType.Direct);
var commandList = _device.CreateCommandList(CommandListType.Direct, commandAllocator, null);
commandList.ResourceBarrierTransition(_screenTexture, ResourceStates.GenericRead, ResourceStates.CopyDestination);
commandList.CopyTextureRegion(destLocation, 0, 0, 0, srcLocation, null);
commandList.ResourceBarrierTransition(_screenTexture, ResourceStates.CopyDestination, ResourceStates.GenericRead);
commandList.Close();
_commandQueue.ExecuteCommandList(commandList);
_fence = _device.CreateFence(0, FenceFlags.None);
_fenceValue = 1;
_fenceEvent = new AutoResetEvent(false);
int localFence = _fenceValue;
_commandQueue.Signal(this._fence, localFence);
_fenceValue++;
// Wait until the previous frame is finished.
if (_fence.CompletedValue < localFence)
{
_fence.SetEventOnCompletion(localFence, _fenceEvent.SafeWaitHandle.DangerousGetHandle());
_fenceEvent.WaitOne();
}
var pnt = _screenTexture.Map(0);
var dataRectangle = new DataRectangle { DataPointer = pnt, Pitch = (int)_screenTexture.Description.Width * 4 };
var dataStream = new DataStream(new DataPointer(pnt, _screenTexture.Description.DepthOrArraySize));