Vk開發配置檢測demo(草稿

//
// Created by sword on 2020/1/27.
//
#ifndef VULKANDEMO_VKAPP_H
#define VULKANDEMO_VKAPP_H
#define SDL_MAIN_HANDLED

#if defined(__ANDROID__)
#define VK_USE_PLATFORM_ANDROID_KHR
#elif defined(__linux__)
#define VK_USE_PLATFORM_XLIB_KHR
#elif defined(_WIN32)
#define VK_USE_PLATFORM_WIN32_KHR
#endif

#include <SDL2/SDL.h>
#include <SDL2/SDL_vulkan.h>
#include <glm/glm.hpp>
#include <vulkan/vulkan.h>

#include <vector>

using std::vector;

class VkApp {
public:
    VkApp() = default;
    int Exec();
    void Init();
    void vkPrintDeviceInfo();

private:
    bool m_Running = true;

    VkInstance   m_instance {};
    VkDevice     m_logicalDevice {};
    VkSurfaceKHR m_surface {};
    vector<VkPhysicalDevice> m_physicalDevices;

    VkResult _CreateDevice();
    VkResult _CreateInstance();
    SDL_Window* m_window = nullptr;

};


#endif //VULKANDEMO_VKAPP_H
//
// Created by sword on 2020/1/27.
//

#include <iostream>
#include <iomanip>
#include "VkApp.h"

VkResult VkApp::_CreateInstance() {
    VkResult                    result = VK_SUCCESS;
    VkApplicationInfo           appInfo = {};
    VkInstanceCreateInfo        instInfo = {};

    unsigned extension_count;
    if(!SDL_Vulkan_GetInstanceExtensions(m_window, &extension_count, nullptr)) {
        std::cout << "Could not get the number of required instance extensions from SDL." << std::endl;
        std::exit(3);
    }
    vector<const char*> extensions(extension_count);
    if(!SDL_Vulkan_GetInstanceExtensions(m_window, &extension_count, extensions.data())) {
        std::cout << "Could not get the names of required instance extensions from SDL." << std::endl;
        std::exit(3);
    }
    vector<const char*> layers;
#if defined(_DEBUG)
    layers.push_back("VK_LAYER_LUNARG_standard_validation");
#endif

    appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    appInfo.pNext = nullptr;
    appInfo.pApplicationName = "DEMO";
    appInfo.applicationVersion = 1;
    appInfo.pEngineName = "LunarG SDK";
    appInfo.engineVersion = 1;
    appInfo.apiVersion = VK_API_VERSION_1_1;

    instInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instInfo.pNext = nullptr;
    instInfo.flags = 0;
    instInfo.pApplicationInfo = &appInfo;
    instInfo.enabledExtensionCount =
            static_cast<uint32_t>(extensions.size());
    instInfo.ppEnabledExtensionNames =
            extensions.data();
    instInfo.enabledLayerCount =
            static_cast<uint32_t>(layers.size());
    instInfo.ppEnabledLayerNames =
            layers.data();

//  Create instance
    result = vkCreateInstance(&instInfo, nullptr, &m_instance);

    if(result == VK_SUCCESS) {
        uint32_t physicalDeviceCount = 0;
        result = vkEnumeratePhysicalDevices(m_instance, &physicalDeviceCount, nullptr);
        if (result == VK_SUCCESS) {
            std::cout << "Device detect succeed, detected "<< physicalDeviceCount
                      << " devices!" << std::endl << std::endl;
            m_physicalDevices.resize(physicalDeviceCount);
            result = vkEnumeratePhysicalDevices(m_instance, &physicalDeviceCount, &m_physicalDevices[0]);
        }
    }

    return result;
}

VkResult VkApp::_CreateDevice() {
    VkResult result;
    VkPhysicalDeviceFeatures supportedFeatures;
    VkPhysicalDeviceFeatures requiredFeatures = {};
    vkGetPhysicalDeviceFeatures( m_physicalDevices[0],
            &supportedFeatures);
    requiredFeatures.multiDrawIndirect      = supportedFeatures.multiDrawIndirect;
    requiredFeatures.tessellationShader     = VK_TRUE;
    requiredFeatures.geometryShader         = VK_TRUE;

    const VkDeviceQueueCreateInfo deviceQueueCreateInfo = {
        VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
        nullptr,
        0,
        0,
        1,
        nullptr
    };

    const VkDeviceCreateInfo deviceCreateInfo = {
            VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
            nullptr,
            0,
            1,
            &deviceQueueCreateInfo,
            0,
            nullptr,
            0,
            nullptr,
            &requiredFeatures
    };

    result = vkCreateDevice(m_physicalDevices[0],
            &deviceCreateInfo,
            nullptr,
            &m_logicalDevice);

    return result;
}

void VkApp::vkPrintDeviceInfo() {
    VkPhysicalDeviceProperties deviceProperties;
    vkGetPhysicalDeviceProperties(m_physicalDevices[0], &deviceProperties);
    std::cout << std::setw(15) << std::left
            << "apiVersion "    << deviceProperties.apiVersion    << std::endl
            << std::setw(15) << std::left
            << "deviceID "      << deviceProperties.deviceID      << std::endl
            << std::setw(15) << std::left
            << "deviceName "    << deviceProperties.deviceName    << std::endl
            << std::setw(15) << std::left
            << "driverVersion " << deviceProperties.driverVersion << std::endl
            << std::setw(15) << std::left
            << "deviceType "    << deviceProperties.deviceType    << std::endl;
}

void VkApp::Init() {
    if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
        std::exit(-3);

    m_window = SDL_CreateWindow("Vulkan", SDL_WINDOWPOS_CENTERED,
                                SDL_WINDOWPOS_CENTERED, 1280, 720,
                                SDL_WINDOW_VULKAN);//|| SDL_WINDOW_BORDERLESS);
    if(m_window == nullptr)
        std::exit(-3);

    if(this->_CreateInstance() == VK_SUCCESS) {
        std::cout << "Create instance succeed." << std::endl;
    } else {
        std::cout << "錕斤拷燙燙燙" << std::endl;
        std::exit(-1);
    }
    vkPrintDeviceInfo();

    if(this->_CreateDevice() == VK_SUCCESS) {
        std::cout << "Create logical device succeed." << std::endl;
    } else {
        std::cout << "Create logical device failed." << std::endl;
        std::exit(-2);
    }

    if(!SDL_Vulkan_CreateSurface(m_window,
            m_instance, &m_surface)) {
        std::exit(-3);
    }

    std::cout << "VK_INIT_FINISHED" << std::endl;
}

int VkApp::Exec() {
    while(m_Running) {
        SDL_Event event;
        while(SDL_PollEvent(&event)) {

            switch(event.type) {
                case SDL_QUIT:
                    m_Running = false;
                    break;
                default:
                    break;
            }

        }
        SDL_Delay(10);
    }

    vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
    SDL_DestroyWindow(m_window);
    SDL_Quit();
    vkDestroyInstance(m_instance, nullptr);

    return 0;
}

#include "VkApp/VkApp.h"
int main(int argc, char* argv[]) {
    auto vkapp = new VkApp;
    vkapp->Init();
    return vkapp->Exec();
}
發佈了19 篇原創文章 · 獲贊 7 · 訪問量 5153
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章