Search code examples
c#directxsharpdx

Resizing swapchain causes Bitmap not to be usable (SharpDX, directX)


I want to resize my swapchain on screen resizing on my windows form application. When I do that, I need to dispose my older deviceContext, buffer, target etc...

Look at the code below :

Public Overrides Sub Resize(Width As Integer, Height As Integer)
    m_backBuffer.Dispose()
    m_d2dContext.Dispose()
    m_2dTarget.Dispose()


    m_swapChain.ResizeBuffers(2, Width, Height, Format.R8G8B8A8_UNorm, SwapChainFlags.None)
    m_backBuffer = m_swapChain.GetBackBuffer(Of Surface)(0)
    Dim properties As BitmapProperties = New BitmapProperties(New SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.R8G8B8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied), 96, 96)

    Dim dxgiDevice As SharpDX.DXGI.Device = m_device.QueryInterface(Of SharpDX.DXGI.Device)()

    Dim d2dDevice As SharpDX.Direct2D1.Device = New SharpDX.Direct2D1.Device(dxgiDevice)
    m_d2dContext = New SharpDX.Direct2D1.DeviceContext(d2dDevice, SharpDX.Direct2D1.DeviceContextOptions.None)

    m_2dTarget = New SharpDX.Direct2D1.Bitmap(m_d2dContext, m_backBuffer, properties)
    m_d2dContext.Target = m_2dTarget

    CType(m_Context, GpuDrawingContext).setRenderTarget(m_d2dContext)

End Sub

The problem when I do that, is that the bitmap I had previously created to display on screen needed a DeviceContext as a parameter for their creation. However, now that I am instanciating a new DeviceContext on resizing, I get the error WrongFactory when I want to draw the bitmap on the deviceContext because their aren't created with the same DeviceContext from where we want to draw them.

Any solutions for the resize function ?


Solution

  • Your code seems to be fundamentally wrong. When handling resize you don't really need to call anything but ResizeBuffers. And you definitely don't need to dispose of m_d2dContext as typically you keep the same one for the lifetime of your application. The rest of your code actually belong to frame rendering, typically at each iteration you do the following:

    • obtain backbuffer (note that it should not be cached because after each Present swap chain will return different backbuffer surface)
    • create d2d bitmap object for backbuffer surface
    • dispose of backbuffer
    • set this d2d bitmap object as render targer of d2d device context
    • dispose of d2d bitmap (it is still alive as it is being used by dc)
    • begin draw
    • draw...
    • end draw
    • reset d2d device context render target
    • present fresh frame