Note
|
グラフィックスの VkPipeline
オブジェクトを作成する際、状態を設定するための流れは以下の通りです。
// ビューポートの状態を例にあげる
VkViewport viewport = {0.0, 0.0, 32.0, 32.0, 0.0, 1.0};
// 状態の値を設定
VkPipelineViewportStateCreateInfo viewportStateCreateInfo;
viewportStateCreateInfo.pViewports = &viewport;
viewportStateCreateInfo.viewportCount = 1;
// 状態の値が設定されたパイプラインを作成する
VkGraphicsPipelineCreateInfo pipelineCreateInfo;
pipelineCreateInfo.pViewportState = &viewportStateCreateInfo;
vkCreateGraphicsPipelines(pipelineCreateInfo, &pipeline);
vkBeginCommandBuffer();
// パイプラインを選択し、状態の静的な値で描画する
vkCmdBindPipeline(pipeline);
vkCmdDraw();
vkEndCommandBuffer();
VkPipeline
が動的な状態を使用している場合、一部のパイプライン情報を作成時に省略し、代わりにコマンドバッファの記録時に設定することができます。新しいフローは以下のようになります。
// ビューポートの状態を例にあげる
VkViewport viewport = {0.0, 0.0, 32.0, 32.0, 0.0, 1.0};
VkDynamicState dynamicState = VK_DYNAMIC_STATE_VIEWPORT;
// 今は使用しない
VkPipelineViewportStateCreateInfo viewportStateCreateInfo;
viewportStateCreateInfo.pViewports = nullptr;
// ここでは使用するビューポートの数を指定する必要がある
viewportStateCreateInfo.viewportCount = 1;
// 状態を動的に設定
VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo;
dynamicStateCreateInfo.dynamicStateCount = 1;
dynamicStateCreateInfo.pDynamicStates = &dynamicState;
// 状態の値が分からない状態でパイプラインを作成する
VkGraphicsPipelineCreateInfo pipelineCreateInfo;
pipelineCreateInfo.pViewportState = &viewportStateCreateInfo;
pipelineCreateInfo.pDynamicState = &dynamicStateCreateInfo;
vkCreateGraphicsPipelines(pipelineCreateInfo, &pipeline);
vkBeginCommandBuffer();
vkCmdBindPipeline(pipeline);
// 記録時のパイプラインの状態を設定する
vkCmdSetViewport(viewport);
vkCmdDraw();
viewport.height = 64.0;
// 描画の間に新しい状態の値を設定する
vkCmdSetViewport(viewport);
vkCmdDraw();
vkEndCommandBuffer();
Note
|
Vulkan はツールなので、他のものと同様に、唯一の答えはありません。 |
実装によっては、VkDynamicState
を使用すると、静的な値を使用するよりもパフォーマンスが低下する場合があります。しかし、動的な状態にすることで、パイプラインオブジェクトのバリエーションを大量に作成する必要がなくなります。アプリケーションによっては、これが有用かもしれません。
仕様書では、動的な状態の寿命について言及している。以下、いくつかの例を挙げて説明する:
// 例1 - 有効
vkCmdSetViewport()
vkCmdBindPipeline() //静的な状態
vkCmdDraw()
// 例2 - 有効
vkCmdBindPipeline() // 静的な状態
vkCmdSetViewport()
vkCmdBindPipeline() // 動的な状態
vkCmdDraw()
// 例3 - 無効 (VUID-vkCmdDraw-None-07831)
vkCmdBindPipeline() // 静的な状態
vkCmdBindPipeline() // 動的な状態
vkCmdDraw()
// 例4 - 無効 (VUID-vkCmdDraw-None-08608)
vkCmdBindPipeline() // 動的な状態
vkCmdBindPipeline() // 静的な状態
vkCmdSetViewport()
vkCmdDraw()
// 例5 - 無効 (VUID-vkCmdDraw-None-07831)
vkCmdSetViewport()
vkCmdBindPipeline() // 静的な状態
vkCmdBindPipeline() // 動的な状態
vkCmdDraw()
// 例6 - 無効 (VUID-vkCmdDraw-None-07831)
vkCmdSetViewport()
vkCmdBindPipeline() // 静的な状態
vkCmdDraw()
vkCmdBindPipeline() // 動的な状態
vkCmdDraw()
動的にすることができる状態のリストは、VkDynamicState にあります。
VK_EXT_extended_dynamic_state
、VK_EXT_extended_dynamic_state2
、VK_EXT_extended_dynamic_state3
、 VK_EXT_vertex_input_dynamic_state
、 VK_EXT_attachment_feedback_loop_dynamic_state
、VK_EXT_color_write_enable
拡張機能は、コンパイルしてバインドするパイプライン状態オブジェクトの数を減らすために追加されました。