2016年7月6日水曜日

Vulkan - インスタンスの生成と破棄

ようやくVulkanインスタンスを生成します.

VkApplicationInfoの初期化

Vulkanインスタンスを生成するために,構造体VkInstanceCreateInfoが必要です.
この構造体を初期化するために,構造体VkApplicationInfoを初期化する必要があります.

構造体VkApplicationInfoは,次のような構造になっています.

struct VkApplicationInfo {
    VkStructureType    sType;
    const void*        pNext;
    const char*        pApplicationName;
    uint32_t           applicationVersion;
    const char*        pEngineName;
    uint32_t           engineVersion;
    uint32_t           apiVersion;
};

sTypeには,VK_STRUCTURE_TYPE_APPLICATION_INFOを設定する必要があります.
pNextはnullptrを設定する必要があります.
apiVersionには,VK_API_VERSION_1_0を設定します.今のところ,他のバージョンを設定するとインスタンスが生成できない場合があります.
pApplicatoinName,applicationVersion,pEngineName,engineVersionは適当でも大丈夫そうですが,今後どうなるかは分かりません.

VkInstanceCreateInfoの初期化

VkApplicationInfoを初期化したら,VkInstanceCreateInfoを初期化します.VkInstanceCreateInfoは次のような構造になっています.

struct VkInstanceCreateInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkInstanceCreateFlags       flags;
    const VkApplicationInfo*    pApplicationInfo;
    uint32_t                    enabledLayerCount;
    const char* const*          ppEnabledLayerNames;
    uint32_t                    enabledExtensionCount;
    const char* const*          ppEnabledExtensionNames;
};

sTypeには,VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFOを設定する必要があります.
pNextはnullptrを設定する必要があります.
flagsは今後のために予約されており,現時点では0を指定します.
pApplicationInfoには,前もって初期化しておいたVkApplicationInfoの変数へのポインタを設定します.
enabledLayerCountには有効にしたいレイヤーの数を,ppEnabledLayerNamesには有効にしたいレイヤー名へのポインタの配列を設定します.
enabledExtensionCount,ppEnabledExtensionNamesもレイヤーと同様に,有効にしたい拡張機能の数と名前へのポインタの配列を設定します.

Vulkanインスタンスの生成

VkInstanceCreateInfoが初期化できたら,次のようなvkCreateInstance()を呼び出してVulkanインスタンスを生成します.

VkResult vkCreateInstance(
    const VkInstanceCreateInfo * pCreateInfo,
    const VkAllocationCallbacks * pAllocator,
    VkInstance * pInstance
);

pCreateInfoには,初期化しておいたVkInstanceCreateInfoの変数へのポインタを渡します.
pAllocatorは,nullptrを指定します.適切な設定をすると,メモリ管理を制御できるのですが,今回は触れません.
pInstanceには,実際に生成されたVulkanインスタンスへのハンドルが設定されるので,VkInstanceの変数へのポインタを渡します.

Vulkanインスタンスの破棄

最後に,次のようなvkDestroyInstance()を呼び出してインスタンスを破棄して終了です.

void vkDestroyInstance(
    VkInstance * pInstance
    const VkAllocationCallbacks * pAllocator
);

実例

以下は,実際にVulkanインスタンスを生成して破棄するだけのコードです.本来は,それぞれのレイヤーがあるかどうか,拡張機能は利用できるかどうか,などを確認すべきですが,ここではそのあたりは省略しています.

#include <iostream>
#include <vector>
#include <vulkan/vulkan.h>

#pragma comment(lib, "vulkan-1")

using namespace std;

int main()
{
    // アプリケーション情報を初期化
    VkApplicationInfo applicationInfo {};
    applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    applicationInfo.pNext = nullptr;
    applicationInfo.pApplicationName = "";
    applicationInfo.applicationVersion = 0;
    applicationInfo.pEngineName = "";
    applicationInfo.engineVersion = 0;
    // VK_VERSION_1_0と間違えないこと
    applicationInfo.apiVersion = VK_API_VERSION_1_0;

    // APIの実引数をダンプしてくれるレイヤーを有効化しておく
    vector<const char *> layerNames {
        "VK_LAYER_LUNARG_api_dump"
    };
    // 今後必要になる拡張機能を有効にしておく
    vector<const char *> extensionNames {
        "VK_KHR_surface",
        "VK_KHR_win32_surface"
    };

    // インスタンス生成情報を初期化
    VkInstanceCreateInfo instanceCreateInfo {};
    instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instanceCreateInfo.pNext = nullptr;
    instanceCreateInfo.flags = 0;
    instanceCreateInfo.pApplicationInfo = &applicationInfo;
    instanceCreateInfo.enabledLayerCount = layerNames.size();
    instanceCreateInfo.ppEnabledLayerNames = layerNames.data();
    instanceCreateInfo.enabledExtensionCount = extensionNames.size();
    instanceCreateInfo.ppEnabledExtensionNames = extensionNames.data();

    // Vulkanインスタンスを生成
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
    if(result != VK_SUCCESS)
    {
        cerr << "Vulkanインスタンスの生成に失敗" << endl;
        return -1;
    }
    cout << "Vulkanインスタンスの生成に成功" << endl;

    vkDestroyInstance(instance, nullptr);
}

サンプルコードは,ryutorion/LearningVulkan (GitHubリポジトリ)の003_CreateInstanceにもあります.

0 件のコメント:

コメントを投稿