Вам не разрешается изменять размер подкачки, если какие-либо виды в зависимости от нее по-прежнему активны. Поэтому убедитесь, что вы вызываете release/распоряжение в RenderTargetView/ShaderResourceViews, созданные из вашего буфера, затем создайте новые, как только вызывается Resize.
Обратите внимание, что эти виды необходимо отделить от конвейера (так что если RenderTargetView, связанный с вашим SwapChain, все еще привязан, убедитесь, что вы отвязали его раньше), иначе dx11 runtime будет ждать их отсоединения перед удалением, поэтому вызов будет по-прежнему терпеть неудачу.
EDIT: Чтобы убедиться, что у вас есть все, что вам нужно, проще всего создать класс swapchain, в котором есть все необходимые данные (обратите внимание, что DX11Device в моем случае также просто обертывает устройство) ,
public class DX11SwapChain : IDX11RenderTarget
{
private DX11Device device;
private IntPtr handle;
private SwapChain swapchain;
public RenderTargetView RenderView { get; protected set; }
public RenderTargetViewDescription RenderViewDesc { get; protected set; }
public Texture2DDescription TextureDesc { get; protected set; }
private Texture2D resource;
public IntPtr Handle { get { return this.handle; } }
}
Вот конструктор:
public DX11SwapChain(DX11Device device, IntPtr handle, Format format, SampleDescription sampledesc)
{
this.device = device;
this.handle = handle;
SwapChainDescription sd = new SwapChainDescription()
{
BufferCount = 1,
ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), format),
IsWindowed = true,
OutputHandle = handle,
SampleDescription = sampledesc,
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput | Usage.ShaderInput,
Flags = SwapChainFlags.None
};
this.swapchain = new SwapChain(device.Factory, device.Device, sd);
this.resource = Texture2D.FromSwapChain<Texture2D>(this.swapchain, 0);
this.TextureDesc = this.resource.Description;
this.RenderView = new RenderTargetView(device.Device, this.resource);
this.RenderViewDesc = this.RenderView.Description;
}
И метод Resize:
public void Resize()
{
this.Resize(0, 0);
}
public void Resize(int w, int h)
{
if (this.RenderView != null) { this.RenderView.Dispose(); }
this.resource.Dispose();
this.swapchain.ResizeBuffers(1,w, h, SharpDX.DXGI.Format.Unknown, SwapChainFlags.AllowModeSwitch);
this.resource = Texture2D.FromSwapChain<Texture2D>(this.swapchain, 0);
this.TextureDesc = this.resource.Description;
this.RenderView = new RenderTargetView(device.Device, this.resource);
}
Кроме того, как раз перед вызовом изменять размер, это хорошо, чтобы позвонить (в конечном итоге вы можете также сделать малая промывка):
device.ImmediateContext.ClearState();
Чтобы отключить все.
Обратите внимание, что если вы используете ресурсы, зависящие от размера, вам также необходимо уведомить ваше приложение (чтобы воссоздать такие элементы, как временный буфер визуализации рендеринга/глубины).
Итак, в этом случае вы можете либо добавить событие Resized в свой класс SwapChain (и прослушать его на вашем холсте). Я не большой поклонник этого лично, так как часто использую несколько SwapChains в одном приложении.
Другой простой способ, чтобы добавить метод:
ResizeResources(int widh,int height);
В классе холст, и вызвать его на renderform размер событие.
Я читал много о том, как избавиться от backbuffer, поэтому я тоже это сделал «_backbuffer.Dispose()», но он не имеет эффекта – Rey
Вы работаете [в режиме отладки] (http://sharpdx.org/forum/4- general/1774-how-to-debug-a-sharpdxexception), чтобы получить всю информацию, которую вы можете? – shoelzer
Если вы имеете в виду, если я запустил его в Debug вместо Release, то да. – Rey