Cannot add DirectX SwapChain during runtime
Asphyre is a cross-platform framework for Delphi and FreePascal.
Brought to you by:
lifepower
(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;
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).