3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Vulkan Tutorial (Drawing a triangle/Setup/Logical device and queues) 日本語訳

Last updated at Posted at 2022-08-05

この記事は Logical device and queues - Vulkan Tutorial の日本語訳です。

Logical device and queues

Introduction

使用する物理デバイスを選択したら、それとのインターフェースとなる論理デバイスをセットアップする必要があります。論理デバイスを作成する手順はインスタンスを作成する手順とよく似ていて、私達が使いたい機能を記述します。使用可能なキューファミリーの中から、どのキューを作成するかを指定する必要もあります。もし異なる要件があるなら、同じ物理デバイスから複数の論理デバイスを作成することもできます。

最初に、論理デバイスのハンドルを格納するメンバーをクラスに追加します。

VkDevice device;

次に、createLogicalDevice関数を追加して、initVulkanから呼び出すようにします。

void initVulkan() {
    createInstance();
    setupDebugMessenger();
    pickPhysicalDevice();
    createLogicalDevice();
}

void createLogicalDevice() {

}

Specifying the queues to be created

論理デバイスの作成には、多くの構造体への詳細設定が必要ですが、その最初はVkDeviceQueueCreateInfoになります。この構造体では、1つのキューファミリーに対して要求するキューの数を設定します。今は、グラフィックス機能を持ったキューにだけ興味があります。

QueueFamilyIndices indices = findQueueFamilies(physicalDevice);

VkDeviceQueueCreateInfo queueCreateInfo{};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = indices.graphicsFamily.value();
queueCreateInfo.queueCount = 1;

現在利用可能なドライバは、各キューファミリーに対して少数のキュー作成だけを許可しますが、実際にはあなたが複数のキューを必要とすることはないでしょう。なぜなら、複数のスレッドそれぞれにコマンドバッファを作成し、低オーバーヘッドな呼び出しでメインスレッドからそれら全てを一度にサブミットできるからです。

Vulkanでは、コマンドバッファ実行のスケジューリングに影響を与える、キューの優先度を、0.0から1.0の間の浮動小数点数で指定できます。これはキューが1つの場合でも必須です。

float queuePriority = 1.0f;
queueCreateInfo.pQueuePriorities = &queuePriority;

Specifying used device features

次に設定する情報は、私達が使用するデバイス機能のセットです。これらはジオメトリシェーダのような、前章でvkGetPhysicalDeviceFeaturesを使ってサポートされているかどうか問い合わせた機能です。今は特別なものは必要ないので、単に定義だけして、全てをVK_FALSEにしておきます。私達がVulkanでもっと面白いことをし始めたとき、この構造体に戻ってくるでしょう。

VkPhysicalDeviceFeatures deviceFeatures{};

Creating the logical device

前の2つの構造体がそろったので、メインのVkDeviceCreateInfo構造体の設定を始めることができます。

VkDeviceCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;

最初に、キューの作成情報とデバイス機能情報へのポインタを追加します。

createInfo.pQueueCreateInfos = &queueCreateInfo;
createInfo.queueCreateInfoCount = 1;

createInfo.pEnabledFeatures = &deviceFeatures;

残りの情報はVkInstanceCreateInfo構造体と似ており、拡張機能とバリデーションレイヤの設定をする必要があります。違いは、今回はデバイス固有のものであることです。

デバイス固有の拡張機能の例としてVK_KHR_swapchainがあり、レンダリングした画像をデバイスからウィンドウに送ることができるようになります。システム内には、この機能が無いVulkanデバイスが存在する可能性もあり、例えばコンピュート処理だけをサポートしているなどの場合です。私達は、スワップチェインの章でまたこの拡張機能に戻ってきます。

以前のVulkan実装では、インスタンスとデバイス固有のバリデーションレイヤは区別されていましたが、今はもはやそうではありません。これは、最新の実装ではVkDeviceCreateInfoenabledLayerCountppEnabledLayerNamesフィールドは無視されるということを意味しています。しかし、古い実装との互換性のため、どちらにせよこれらを設定しておくほうが良いでしょう。

createInfo.enabledExtensionCount = 0;

if (enableValidationLayers) {
    createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
    createInfo.ppEnabledLayerNames = validationLayers.data();
} else {
    createInfo.enabledLayerCount = 0;
}

今はデバイス固有の拡張機能は必要ありません。

以上で、vkCreateDevice関数を呼び出して、論理デバイスを作成する準備ができました。

if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
    throw std::runtime_error("failed to create logical device!");
}

引数は、インターフェースで接続したい物理デバイス、さきほど設定したキューと使用方法の情報、オプションのアロケーションコールバックへのポインタ、論理デバイスのハンドルを格納する変数へのポインタです。インスタンス作成関数と同様、この呼出は、存在しない拡張機能を有効にしたり、サポートされていない機能を要求した場合にエラーを返すことがあります。

デバイスは、cleanup内でvkDestroyDevice関数を呼び出して破棄する必要があります。

void cleanup() {
    vkDestroyDevice(device, nullptr);
    ...
}

論理デバイスはインスタンスとは直接関わらないので、パラメータには含まれません。

Retrieving queue handles

キューは論理デバイスと一緒に自動的に作成されていますが、私達はまだそれに対するハンドルを持っていません。まず、グラフィックキューへのハンドルを格納するメンバ変数をクラスに追加します。

VkQueue graphicsQueue;

デバイスのキューは、デバイスが破棄されるときに自動的にクリーンアップされるので、cleanupでは何もする必要がありません。

それぞれのキューファミリーからキューのハンドルを取得するには、vkGetDeviceQueue関数を使うことができます。引数は、論理デバイス、キューファミリー、キューインデックス、キューのハンドルを格納する変数へのポインタです。キューファミリーから1つのキューだけを作成するので、単にインデックス0を使います。

vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);

論理デバイスとキューハンドルがあれば、グラフィックスカードを使って実際に何かを始めることができます!次のいくつかの章では、ウィンドウシステムに結果を送るためのリソースをセットアップします。

C++ code

前の記事
次の記事

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?