VeldridでFenceを使う

提供: MonoBook
ナビゲーションに移動 検索に移動

一定間隔でUpdate()とDraw()が呼ばれる以下のような実装があるとする。 この際にFenceを使うことで「CPUがメインのUpdate()」と「GPUがメインのDraw()」をマルチスレッドを使わずに並走させることができる。 SubmitCommands()した内容が別スレッド(GPU)で実行され、処理が終わるとFenceがシグナル状態になる感じだ。

class App 
{
    Sdl2Window     _window;
    GraphicsDevice _graphicsDevice;
    Fence          _drawFence;

    // 初期化
    void Initialized()
    {
        // WindowとGraphicsDeviceを生成
        CreateWindow();
        CreateGraphicsDevice();

        // 
        var factory = _graphicsDevice.ResourceFactory;

        // CommandListを作る
        _commandList = factory.CreateCommandList();

        // Fenceを作る
        _drawFence = factory.CreateFence(signaled:true);
    }

    //  一定間隔で呼ばれる
    void Update()
    {
    }

    //  一定間隔で呼ばれる
    void Draw() 
    {
        // 前回のDraw()が終わるまで待つ
        _graphicsDevice.WaitForFence(_drawFence);

        // Fenceを再利用
        _drawFence.Reset();

        // --------------------------------

        // 描画コマンドを組み立て
        _commandList.Begin();
            // 〜〜〜 省略 〜〜〜
        _commandList.End();
        
        // 描画コマンドを送信
        _graphicsDevice.SubmitCommands(_commandList, _drawFence);
        
        // Fenceを使う場合はここで描画完了を待たない。
        // Fenceを使わず描画完了を待つ場合は以下をコメントアウト
        //_graphicsDevice.WaitForIdel();
    }
}