2016年7月6日水曜日

Vulkan - インスタンス拡張機能の列挙

拡張機能とは

レイヤーの列挙,でも書いたように,レイヤーはVulkan APIによって発行されるコマンドに割り込みをかけるものです.

一方,拡張機能はVulkanのコマンドなどを追加します.

インスタンス拡張機能の列挙

拡張機能を列挙するための手順は,レイヤーを列挙する際の手順に似ています.インスタンス拡張機能の場合,次のようなvkEnumerateInstanceExtensionProperties()を呼び出します.

VkResult vkEnumerateInstanceExtensionProperties(
    const char * pLayerName,
    uint32_t * pPropertyCount,
    VkExtensionProperties * pProperties
);

仮引数の名前を見ると分かるように,インスタンス拡張機能はレイヤーに紐付いています.ただし,pLayerNameにnullptrを指定することも可能で,その場合はデフォルトで利用可能なインスタンス拡張が列挙されます.

インスタンス拡張機能の情報は,次のような構造体に保存されます.

struct VkExtensionProperties {
    char        extensionName[VK_MAX_EXTENSION_NAME_SIZE];
    uint32_t    specVersion;
};

以下の例では,利用可能なレイヤー名を全て取得し,更にnullptrを追加した上で,インスタンス拡張を列挙して,その情報をダンプしています.

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

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

using namespace std;

class version
{
public:
    version(uint32_t value) : mValue(value) {}

    uint32_t value() const { return mValue; }
    uint32_t major() const { return VK_VERSION_MAJOR(mValue); }
    uint32_t minor() const { return VK_VERSION_MINOR(mValue); }
    uint32_t patch() const { return VK_VERSION_PATCH(mValue); }

private:
    uint32_t mValue;
};

std::ostream & operator<<(std::ostream & out, const version & v)
{
    out << v.major() << "." << v.minor() << "." << v.patch();
    return out;
}

int main()
{
    VkResult result = VK_SUCCESS;
    vector<VkLayerProperties> layers {};
    do {
        uint32_t count = 0;
        result = vkEnumerateInstanceLayerProperties(&count, nullptr);
        if(result != VK_SUCCESS)
        {
            break;
        }

        layers.resize(count);
        result = vkEnumerateInstanceLayerProperties(&count, layers.data());
    } while(result == VK_INCOMPLETE);

    // レイヤー名の配列を生成
    vector<const char *> layerNames(layers.size() + 1);
    for(auto i = 0; i < layers.size(); ++i)
    {
        layerNames[i] = layers[i].layerName;
    }
    layerNames[layers.size()] = nullptr;

    for(auto layerName : layerNames)
    {
        cout << (layerName ? layerName : "No Layer Name") << endl;

        // レイヤーに対応する拡張の取得
        vector<VkExtensionProperties> extensions;
        do {
            uint32_t count = 0;
            result = vkEnumerateInstanceExtensionProperties(layerName, &count, nullptr);
            if(result != VK_SUCCESS)
            {
                break;
            }

            extensions.resize(count);
            result = vkEnumerateInstanceExtensionProperties(layerName, &count, extensions.data());
        } while(result == VK_INCOMPLETE);

        for(auto & extension : extensions)
        {
            cout << "\tExtension Name        : " << extension.extensionName << endl;
            cout << "\tSpecification Version : " << version(extension.specVersion) << endl;
            cout << endl;
        }
    }
}

GitHubのリポジトリryutorion/LearningVulkanの002_EnumerateInstanceExtensionsに実際のコードがあります.

0 件のコメント:

コメントを投稿