Created
October 3, 2020 19:25
-
-
Save untodesu/ca793ad8500e2ae49493786f1b2eeae8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// vulkan.cpp -- internal vulkan wrapper. | |
// Copyright (C) 2020, Voxelius team. | |
// | |
#include <voxelius/engine.h> | |
#include "debug.h" | |
#include "vulkan.h" | |
const bool VkQueueIndices::IsValid(void) const | |
{ | |
if(m_graphics == -1) | |
return false; | |
return true; | |
} | |
VkPhysicalDeviceInfo::VkPhysicalDeviceInfo(void) : m_rating(0) | |
{ | |
} | |
VkPhysicalDeviceInfo::VkPhysicalDeviceInfo(VkPhysicalDevice dev) : m_rating(0) | |
{ | |
vkGetPhysicalDeviceFeatures(dev, &m_features); | |
vkGetPhysicalDeviceProperties(dev, &m_properties); | |
uint32_t numQueueProps; | |
vkGetPhysicalDeviceQueueFamilyProperties(dev, &numQueueProps, nullptr); | |
m_queueProps.resize(numQueueProps); | |
vkGetPhysicalDeviceQueueFamilyProperties(dev, &numQueueProps, m_queueProps.data()); | |
int qpi = 0; | |
for(VkQueueFamilyProperties &prop : m_queueProps) { | |
if(prop.queueFlags & VK_QUEUE_GRAPHICS_BIT) | |
m_queueIndices.m_graphics = qpi; | |
qpi++; | |
} | |
if(m_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) | |
m_rating += 1000; | |
m_rating += m_properties.limits.maxImageDimension2D; | |
} | |
const int VkPhysicalDeviceInfo::GetRating(void) const | |
{ | |
return m_rating; | |
} | |
VxVulkan::VxVulkan(IVxEngine *pEngine) : m_pEngine(pEngine) | |
{ | |
} | |
void VxVulkan::CreateInstance(SDL_Window *pWindow) | |
{ | |
VkApplicationInfo appInfo; | |
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; | |
appInfo.apiVersion = VK_API_VERSION_1_0; | |
appInfo.pEngineName = "Voxelius"; | |
appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1); | |
uint32_t numExtensions; | |
SDL_Vulkan_GetInstanceExtensions(pWindow, &numExtensions, nullptr); | |
std::vector<const char *> extensions(numExtensions); | |
SDL_Vulkan_GetInstanceExtensions(pWindow, &numExtensions, extensions.data()); | |
extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); | |
VkInstanceCreateInfo createInfo; | |
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; | |
createInfo.enabledLayerCount = 0; | |
createInfo.pApplicationInfo = &appInfo; | |
createInfo.enabledExtensionCount = (uint32_t)extensions.size(); | |
createInfo.ppEnabledExtensionNames = extensions.data(); | |
VkResult result = vkCreateInstance(&createInfo, nullptr, &m_instance); | |
VX_AssertMsg(result == VK_SUCCESS, "Failed to create VkInstance."); | |
} | |
void VxVulkan::DestroyInstance(void) | |
{ | |
vkDestroyInstance(m_instance, nullptr); | |
} | |
void VxVulkan::CreateSurface(SDL_Window *pWindow) | |
{ | |
SDL_bool result = SDL_Vulkan_CreateSurface(pWindow, m_instance, &m_surface); | |
VX_AssertMsg(result == SDL_TRUE, "Failed to crate VkSurfaceKHR"); | |
} | |
void VxVulkan::DestroySurface(void) | |
{ | |
vkDestroySurfaceKHR(m_instance, m_surface, nullptr); | |
} | |
void VxVulkan::PickPhysicalDevice(void) | |
{ | |
uint32_t numDevices; | |
vkEnumeratePhysicalDevices(m_instance, &numDevices, nullptr); | |
VX_AssertMsg(numDevices > 0, "No Vulkan-compatible GPU found."); | |
std::vector<VkPhysicalDevice> devices(numDevices); | |
vkEnumeratePhysicalDevices(m_instance, &numDevices, devices.data()); | |
std::vector<VkPhysicalDeviceInfo> infos(numDevices); | |
for(uint32_t i = 0; i < numDevices; i++) | |
infos[i] = VkPhysicalDeviceInfo(devices[i]); | |
uint32_t di = 0; | |
int maxrate = -1; | |
for(uint32_t i = 0; i < numDevices; i++) { | |
if(infos[i].m_queueIndices.IsValid()) { | |
int rating = infos[i].GetRating(); | |
if(rating > maxrate) { | |
maxrate = rating; | |
di = i; | |
} | |
} | |
} | |
VX_AssertMsg(maxrate != -1, "No suitable GPU found."); | |
m_pEngine->Log(VX_LOG_INFO, "Using %s (rating=%d)", infos[di].m_properties.deviceName, maxrate); | |
m_physDeviceInfo = infos[di]; | |
m_physDevice = devices[di]; | |
} | |
void VxVulkan::CreateDevice(void) | |
{ | |
float queuePriority = 1.0; | |
VkDeviceQueueCreateInfo queueInfo; | |
queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; | |
queueInfo.queueFamilyIndex = (uint32_t)m_physDeviceInfo.m_queueIndices.m_graphics; | |
queueInfo.queueCount = 1; | |
queueInfo.pQueuePriorities = &queuePriority; | |
VkDeviceCreateInfo createInfo; | |
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; | |
createInfo.enabledExtensionCount = 0; | |
createInfo.pEnabledFeatures = &m_physDeviceInfo.m_features; | |
createInfo.pQueueCreateInfos = &queueInfo; | |
createInfo.queueCreateInfoCount = 1; | |
VkResult result = vkCreateDevice(m_physDevice, &createInfo, nullptr, &m_device); | |
VX_AssertMsg(result == VK_SUCCESS, "Failed to create VkDevice."); | |
vkGetDeviceQueue(m_device, (uint32_t)m_physDeviceInfo.m_queueIndices.m_graphics, 0, &m_qGraphics); | |
} | |
void VxVulkan::DestroyDevice(void) | |
{ | |
vkDestroyDevice(m_device, nullptr); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// vulkan.h -- internal vulkan wrapper. | |
// Copyright (C) 2020, Voxelius team. | |
// | |
#ifndef VX_VULKAN_H_ | |
#define VX_VULKAN_H_ | |
#include <SDL2/SDL.h> | |
#include <SDL2/SDL_vulkan.h> | |
#include <vulkan/volk.h> | |
#include <vector> | |
class IVxEngine; | |
class VkQueueIndices { | |
public: | |
const bool IsValid(void) const; | |
public: | |
int m_graphics = -1; | |
}; | |
class VkPhysicalDeviceInfo { | |
public: | |
VkPhysicalDeviceInfo(void); | |
VkPhysicalDeviceInfo(VkPhysicalDevice dev); | |
const int GetRating(void) const; | |
public: | |
VkPhysicalDeviceFeatures m_features; | |
VkPhysicalDeviceProperties m_properties; | |
std::vector<VkQueueFamilyProperties> m_queueProps; | |
VkQueueIndices m_queueIndices; | |
private: | |
int m_rating; | |
}; | |
class VxVulkan { | |
public: | |
VxVulkan(IVxEngine *pEngine); | |
void CreateInstance(SDL_Window *pWindow); | |
void DestroyInstance(void); | |
void CreateSurface(SDL_Window *pWindow); | |
void DestroySurface(void); | |
void PickPhysicalDevice(void); | |
void CreateDevice(void); | |
void DestroyDevice(void); | |
private: | |
IVxEngine *m_pEngine; | |
VkInstance m_instance; | |
VkPhysicalDevice m_physDevice; | |
VkPhysicalDeviceInfo m_physDeviceInfo; | |
VkDevice m_device; | |
VkQueue m_qGraphics; | |
VkSurfaceKHR m_surface; | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment