#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
#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();
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);
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();
}