Menu

#1 Cannot add DirectX SwapChain during runtime

1.0
wont-fix
nobody
2016-06-22
2016-01-24
Lifepower
No

(This has been reported earlier on GitHub repo)

At the moment it is not possible to add a DirectX SwapChain at runtime, because the TSwapChains.Add function does not recreate the corresponding TDXnDevice.DXSwapChains array.

I added this feature, since I required it. It works and does its purpose. But I'm not sure if I did this correctly.

In PXL.SwapChains.pas:

TCustomSwapChainDevice = class(TCustomStateDevice)
public
  { This method should be implemented by the derived classes to recreate the DX swap chains after a new swap chain
    has been added at runtime. The method must be called after the new swap chain has been added using @link(TSwapChains.Add). }
  function RecreateSwapChains: Boolean; virtual; abstract;
end;

In PXL.Devices.DX11 (also did this for DX7 and DX9)

interface
type
  TDX11Device = class(TCustomSwapChainDevice)
  public
    function RecreateSwapChains: Boolean; override;
  end;

implementation

function TDX11Device.RecreateSwapChains: Boolean;
begin
  if not FDXSwapChains.Recreate(SwapChains) then
  begin
    FDXSwapChains.Clear;
    ReleaseFactory;
    ReleaseDeviceContext;
    Exit(False);
  end;

  Result := True;
end;

And then to use it:

procedure TForm1.Button_AddClick(Sender: TObject);
begin
  ...
  EngineDevice.SwapChains.Add(OutputPanels[i].Handle, DisplaySize, 1, False,
    TPixelFormat.A8R8G8B8);
  EngineDevice.RecreateSwapChains;
end;

Discussion

  • Lifepower

    Lifepower - 2016-06-22
    • status: open --> wont-fix
     
  • Lifepower

    Lifepower - 2016-06-22

    After looking further into this, once device has been initialized, swap chains do not accept changes except resizing, which is invoked by TCustomSwapChainDevice.Resize.

    Currently, due to how it is designed, TCustomSwapChainDevice.SwapChains does not forcefully prevent you from calling "Add" or trying to change swap chain contents once device has been initialized, but that really constritutes an undefined behavior.

    The correct approach would be to finalize device, adjust content of swap chains and then initialize it again. The reason for this is that - although for existing Direct3D providers "RecreateSwapChains" may sort of work, other providers such as OpenGL may require creating shared context lists and likely re-creating contexts (remember that OpenGL extensions are bound to specific window handle, so if you add or change handles, you need to reload extensions and likely all your resources).

     

Log in to post a comment.