27

Vulkan で同期を処理するには、いくつかの方法があります。これは私がそれを理解する方法です:

  • フェンスは GPU から CPU への同期です。
  • セマフォは GPU から GPU への同期であり、(同じまたは異なるキューで) キューの送信を同期するために使用されます。
  • イベントはより一般的で、リセットされ、CPU と GPU の両方でチェックされます。
  • バリアは、コマンド バッファー内の同期に使用されます。

私の場合、2 つのコマンド バッファがあります。そして、最初のコマンド バッファの後に 2 番目のコマンド バッファを実行する必要があります。

submitInfo.pCommandBuffers = &firstCommandBuffer;
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);

// wait for first command buffer to finish
submitInfo.pCommandBuffers = &secondCommandBuffer;
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);

これに最適な同期の種類は何ですか? 使用する場合vkQueueWaitIdle(queue)),は、フェンスを使用するのと同じことですか、それともイベントまたはセマフォを使用する必要がありますか?

複数のコマンドバッファを同時にキューに送信した場合:

std::vector<VkCommandBuffer> submitCmdBuffers = {
        firstCommandBuffer,
        secondCommandBuffer
    };
    submitInfo.commandBufferCount = submitCmdBuffers.size();
    submitInfo.pCommandBuffers = submitCmdBuffers.data();

1 つ目と 2 つ目を同期する方法はまだありますか?

4

2 に答える 2

18

最初のコマンド バッファーは、深度テストがオンになっているレンダリング オブジェクトです。2 番目のコマンド バッファーは、深度テストをオフにしてメッシュのアウトラインをレンダリングしています。他のオブジェクトの上になければならないからです。

この場合、何が必要かは、それらのコマンド バッファが何であるかによって異なります。

それらが同じレンダー パス インスタンス内で実行されるセカンダリ コマンド バッファーである場合、同期化は必要ありません。セカンダリ コマンド バッファーの深度テクスチャから手動で読み取っている場合を除きます。なんで?

セクション 2.2.1 のAPI の順序付けがあなたを保護するからです。レンダー パス インスタンス内のデプス テストとデプス ライティングは、常にAPI の順序で処理されます。したがって、後のコマンドは、同じ CB であろうと別の CB であろうと、深度テスト/書き込みに関して順序付けられます。

ただし、シェーダーからその深度バッファーを読み取る必要がある場合、またはコマンド バッファーが別のレンダー パス インスタンスにある場合は、イベントを介して明示的に同期する必要があります。

この場合、vkCmdSetEventコマンドのステージ マスクは、深度値を書き込むステージである必要があります。これはEARLY_FRAGMENT_TESTS_BITまたはの可能性がありますLATE_FRAGMENT_TESTS_BIT。安全のため、両方を使用してください。ただし、おそらく同じカラー バッファーを更新するため、COLOR_ATTACHMENT_OUTPUT_BITステージも必要です。このコマンドを最初のコマンド バッファの最後 (またはすべての深度書き込みが完了した後) に挿入します。

の場合、vkCmdWaitEventそれを必要とするパイプライン ステージで待機する必要があります。あなたの場合、これは再びフラグメント テストとカラー アタッチメントです。ただし、シェーダー ステージが深度を読み取る場合は、待機コマンドでそのステージも必要です。

メモリが関係vkCmdWaitEventするため、深度バッファとカラー バッファに対するメモリ依存も使用する必要があります。

しかし実際には、これらのコマンド バッファーを可能な限り同じレンダー パス インスタンスに配置する必要があるのは、こうした複雑さのすべてが理由です。そうできない唯一の理由は、シェーダーで深度バッファーから読み取る必要がある場合です。

于 2016-05-27T13:44:10.057 に答える
6

あなたのシナリオでは、イベントを使用する必要があります。これらは、一度に送信した場合でも、2 つのコマンド バッファーの実行を特定の順序で同期するための最も軽量な同期オブジェクトである必要があります。ただし、イベントは異なるキューでは機能しないことに注意してください。1 つしか使用しない場合は、イベントを使用し、src および dst パイプライン ステージ マスクをできるだけ狭くしてください。

セマフォは、コマンド バッファの実行を同期するもう 1 つの方法ですが、これらはキューの送信に対してのみ機能するため、イベントよりも重量があります。

于 2016-05-27T11:59:41.077 に答える