Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What is going on with this article?
@tositada_nakada

初めてのVulkanプログラミング step3 スワップチェーンの作成

More than 1 year has passed since last update.

目次に戻る

ソースコードは以下の場所に置いておきます。各自のバージョンに合わせたプロパティ設定をしてから自由にご利用ください。

GitHub

スワップチェーン

VUlkanでは、標準のデフォルトのフレームバッファがありません。画面に表示したい場合、レンダリング可能な一連のバッファーを持つインフラをを作成する必要があります。これらのバッファとプロパティは、スワップチェーンと呼ばれます。

スワップチェーンのサポート確認

vkGetPhysicalDeviceSurfaceSupportKHR()関数はあるデバイスが、スワップチェーンをサポートしているか確認します。

    VkBool32 surfaceSupport;
    vkGetPhysicalDeviceSurfaceSupportKHR(_renderer->GetVulkanPhysicalDevice(), 0, _surface, &surfaceSupport);

デバイス拡張

スワップチェーンはGPUが描写する画像バッファーのインフラであるため、GPUレベルの拡張が必要です。
そのためサンプルコードではVK_KHR_SWAPCHAIN_EXTENSION_NAMEを挿入しています

使用するデバイス拡張をvkDeviceCreateInfoに入れる

    std::vector<const char*>    _device_extensions;
    _device_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
//vkdevicecreateinfoに挿入
    device_create_info.enabledExtensionCount = _device_extensions.size();
    device_create_info.ppEnabledExtensionNames = _device_extensions.data();

プロパティの取得

画面に表示するための互換性がないため、スワップチェーンが利用可能かどうかの確認だけでは、スワップチェーンを使用できません。
スワップチェーンに必要な情報としては、3種類の情報が必要です。

・基本的なサーフェスの機能 (スワップチェーンの画面の大きさ、バッファの数、etc...)
・描写フォーマット (24ビットカラー、白黒画像、赤だけの画面、etc...)
・利用可能なプレゼンテーションモード

    //基本的なサーフェスの機能

    vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, _surface, &_surface_capabilities);

    //描写フォーマット
    uint32_t format_count = 0;
    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu, _surface, &format_count, nullptr);
    std::vector<VkSurfaceFormatKHR>formats(format_count);
    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu, _surface, &format_count, formats.data());
    std::cout << "DeviceSurfaceFormats: " << format_count << std::endl;
    for (int i = 0; i < format_count;i++) {
        std::cout << "Format: " << formats[i].format << std::endl;
    }

    //利用可能なプレゼンテーションモード
    uint32_t present_mode_count;
    vkGetPhysicalDeviceSurfacePresentModesKHR(_renderer->GetVulkanPhysicalDevice(),_surface, &present_mode_count, nullptr);
    std::vector<VkPresentModeKHR>present_mode_list(present_mode_count);
    vkGetPhysicalDeviceSurfacePresentModesKHR(_renderer->GetVulkanPhysicalDevice(), _surface, &present_mode_count, present_mode_list.data());
    std::cout << "DeviceSurfaceFormats: " << present_mode_count << std::endl;
    for (int i = 0; i < present_mode_count; i++) {
        std::cout << "support present mode: " << present_mode_list[i] << std::endl;
    }

プレゼンテーションモード

プレゼンテーションモードは、実際に画面に描写するときのアルゴリズムを指定します。
vulkanでは、以下の4つがあります。

VK_PRESENT_MODE_IMMEDIATE_KHR

送信された画像をすぐに表示します。

VK_PRESENT_MODE_FIFO_KHR

ディスプレイのリフレッシュレートを保持するために単一のキューを使用します。新しい要求がキューにおくられ、1つの要求がキューの先頭からでます。キューがいっぱいになったときには、待ち時間が発生します。

VK_PRESENT_MODE_MAILBOX_KHR

キューがいっぱいになったときにアプリケーションをブロックせずに、すぐに表示します。トリプルバッファリングに実装する際に使用します。これによりダブルバッファリングを使う場合よりも滑らかにに表示することができる可能性があります。その代わりに処理が重くなる可能性があります

presentmode.JPG

スワップチェーンの作成

実行時に必要な情報がそろったのでスワップチェーンを作成します

まずサーフェスを指定します。

    VkSwapchainCreateInfoKHR swapchain_create_info = {};
    swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    swapchain_create_info.pNext = nullptr;
    swapchain_create_info.flags = 0;
    swapchain_create_info.surface = _surface;

基本的なサーフェスの機能を指定します
imageformat B8G8R8A8...フルビットカラーです。UNORM...8ビットカラーだけど0.0~1.0fとして変換するよ
color space...色空間を指定
imageArrayLayers...マルチビュー/ステレオサーフェスの数 非立体画像の場合は1

    swapchain_create_info.minImageCount = _surface_capabilities.minImageCount;
    swapchain_create_info.imageFormat = VK_FORMAT_B8G8R8A8_UNORM; //_surface_format.format
    swapchain_create_info.imageColorSpace = _surface_format.colorSpace;
    swapchain_create_info.imageExtent.width = _surface_size_x;
    swapchain_create_info.imageExtent.height = _surface_size_y;
    swapchain_create_info.imageArrayLayers = 1;

描写フォーマットのオプションを指定します

imageUsage ... imageの使い方 、
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT...Image viewを作成して、colorを含んだ,Imageをフレームバッファーに渡す。

sharingmode ...Imageのキューへの共有
一つのキューファミリーにシェアする。

queueFamilyIndexCount... 他のキューファミリーと共有する場合は、入れる。SHARING_MODE_CONCURRENTの時
preTransform...画像を表示する際に画像を回転する。
compositeAlpha...Alpha値の値.デフォルトで1.0にする.

    swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
    swapchain_create_info.queueFamilyIndexCount = 0;
    swapchain_create_info.pQueueFamilyIndices = nullptr;
    swapchain_create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
    swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;

プレゼンテーションモードを指定します
clipped...表示よりも外側にあるrenderは破棄しますか?。true

    swapchain_create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR;
    swapchain_create_info.clipped =VK_TRUE;
    swapchain_create_info.oldSwapchain = VK_NULL_HANDLE;

最後vkCreateSwapchainKHR関数を呼び出し完成です

     vkCreateSwapchainKHR(gpu,&swapchain_create_info,nullptr,&_swapchain);

連絡先

tweeter: tositada_nakada
mail: nakadasanda@outlook.com

寄付

paypal: tositada_nakada
Amazon:欲しいものリスト

1
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
tositada_nakada
石川で大学生やっています。 使える言語:vulkan/physix/c++/日本語

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1
Help us understand the problem. What is going on with this article?