ULRE/example/Vulkan/VKInstance.cpp

286 lines
9.2 KiB
C++
Raw Normal View History

2019-04-09 00:22:26 +08:00
#include"VKInstance.h"
#include"VKSurfaceExtensionName.h"
2019-04-18 22:10:24 +08:00
#include"VKPhysicalDevice.h"
#include<iostream>
2019-04-09 00:22:26 +08:00
VK_NAMESPACE_BEGIN
2019-04-18 16:06:44 +08:00
Device *CreateRenderDevice(VkInstance,const PhysicalDevice *,Window *);
2019-04-09 00:22:26 +08:00
namespace
{
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance,const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,const VkAllocationCallbacks *pAllocator,VkDebugUtilsMessengerEXT *pDebugMessenger)
{
auto func=(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance,"vkCreateDebugUtilsMessengerEXT");
if(func)
{
return func(instance,pCreateInfo,pAllocator,pDebugMessenger);
}
else
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
}
void DestroyDebugUtilsMessengerEXT(VkInstance instance,VkDebugUtilsMessengerEXT debugMessenger,const VkAllocationCallbacks *pAllocator)
{
auto func=(PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance,"vkDestroyDebugUtilsMessengerEXT");
if(func)
{
func(instance,debugMessenger,pAllocator);
}
}
VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,VkDebugUtilsMessageTypeFlagsEXT messageType,const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,void *pUserData)
{
std::cerr<<"validation layer: "<<pCallbackData->pMessage<<std::endl;
return VK_FALSE;
}
bool CreateDebugReportCallbackEXT(VkInstance instance,const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,const VkAllocationCallbacks *pAllocator,VkDebugReportCallbackEXT *pCallback)
{
auto func=(PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance,"vkCreateDebugReportCallbackEXT");
if(func)
{
func(instance,pCreateInfo,pAllocator,pCallback);
return(true);
}
else
{
return(false);
}
}
bool DestroyDebugReportCallbackEXT(VkInstance instance,VkDebugReportCallbackEXT callback,const VkAllocationCallbacks *pAllocator)
{
auto func=(PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance,"vkDestroyDebugReportCallbackEXT");
if(func)
{
func(instance,callback,pAllocator);
return(true);
}
else
{
return(false);
}
}
VKAPI_ATTR VkBool32 VKAPI_CALL dbgFunc(VkDebugReportFlagsEXT msgFlags,VkDebugReportObjectTypeEXT objType,uint64_t srcObject,
size_t location,int32_t msgCode,const char *pLayerPrefix,const char *pMsg,
void *pUserData)
{
if(msgFlags&VK_DEBUG_REPORT_ERROR_BIT_EXT)
{
std::cout<<"ERROR: ";
}
else if(msgFlags&VK_DEBUG_REPORT_WARNING_BIT_EXT)
{
std::cout<<"WARNING: ";
}
else if(msgFlags&VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
{
std::cout<<"PERFORMANCE WARNING: ";
}
else if(msgFlags&VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
{
std::cout<<"INFO: ";
}
else if(msgFlags&VK_DEBUG_REPORT_DEBUG_BIT_EXT)
{
std::cout<<"DEBUG: ";
}
std::cout<<"["<<pLayerPrefix<<"] Code "<<msgCode<<" : "<<pMsg<<std::endl;
/*
* false indicates that layer should not bail-out of an
* API call that had validation failures. This may mean that the
* app dies inside the driver due to invalid parameter(s).
* That's what would happen without validation layers, so we'll
* keep that behavior here.
*/
return false;
}
}//namespace
Instance *CreateInstance(const UTF8String &app_name)
2019-04-09 00:22:26 +08:00
{
VkApplicationInfo app_info;
VkInstanceCreateInfo inst_info;
CharPointerList ext_list;
2019-04-09 00:22:26 +08:00
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
app_info.pNext = nullptr;
app_info.pApplicationName = app_name.c_str();
app_info.applicationVersion = 1;
app_info.pEngineName = "CMGameEngine/ULRE";
app_info.engineVersion = 1;
app_info.apiVersion = VK_API_VERSION_1_0;
ext_list.Add(VK_KHR_SURFACE_EXTENSION_NAME);
ext_list.Add(HGL_VK_SURFACE_EXTENSION_NAME); //此宏在VKSurfaceExtensionName.h中定义
ext_list.Add(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
2019-04-19 18:09:08 +08:00
ext_list.Add(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
2019-04-20 00:51:03 +08:00
const char *validation_layers[]=
{
2019-04-19 18:09:08 +08:00
// "VK_LAYER_LUNARG_api_dump",
2019-04-20 19:20:13 +08:00
// "VK_LAYER_LUNARG_assistant_layer",
2019-04-19 18:09:08 +08:00
"VK_LAYER_LUNARG_core_validation",
2019-04-20 00:51:03 +08:00
// "VK_LAYER_LUNARG_device_simulation",
2019-04-20 19:20:13 +08:00
// "VK_LAYER_LUNARG_monitor",
2019-04-19 18:09:08 +08:00
"VK_LAYER_LUNARG_object_tracker",
"VK_LAYER_LUNARG_standard_validation",
"VK_LAYER_LUNARG_parameter_validation",
2019-04-19 18:09:08 +08:00
// "VK_LAYER_LUNARG_vktrace",
"VK_LAYER_RENDERDOC_Capture",
2019-04-19 18:09:08 +08:00
2019-04-20 19:20:13 +08:00
// "VK_LAYER_KHRONOS_validation",
2019-04-20 16:12:22 +08:00
// "VK_LAYER_NV_nsight-sys",
2019-04-19 18:09:08 +08:00
2019-04-20 00:51:03 +08:00
"VK_LAYER_GOOGLE_unique_objects",
"VK_LAYER_GOOGLE_threading"
};
2019-04-09 00:22:26 +08:00
inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
inst_info.pNext = nullptr;
inst_info.flags = 0;
inst_info.pApplicationInfo = &app_info;
inst_info.enabledExtensionCount = ext_list.GetCount();
inst_info.ppEnabledExtensionNames = ext_list.GetData();
inst_info.enabledLayerCount = sizeof(validation_layers)/sizeof(const char *);
inst_info.ppEnabledLayerNames = validation_layers;
2019-04-09 00:22:26 +08:00
VkInstance inst;
2019-04-09 00:22:26 +08:00
if(vkCreateInstance(&inst_info,nullptr,&inst)==VK_SUCCESS)
return(new Instance(inst,ext_list));
return(nullptr);
2019-04-09 00:22:26 +08:00
}
Instance::Instance(VkInstance i,CharPointerList &el)
2019-04-09 00:22:26 +08:00
{
inst=i;
ext_list=el;
2019-04-09 00:22:26 +08:00
{
uint32_t layerCount;
vkEnumerateInstanceLayerProperties(&layerCount,nullptr);
layer_properties.SetCount(layerCount);
vkEnumerateInstanceLayerProperties(&layerCount,layer_properties.GetData());
debug_out(layer_properties);
}
{
uint32_t prop_count;
vkEnumerateInstanceExtensionProperties(nullptr,&prop_count,nullptr);
extension_properties.SetCount(prop_count);
vkEnumerateInstanceExtensionProperties(nullptr,&prop_count,extension_properties.GetData());
debug_out(extension_properties);
}
debug_report_callback=nullptr;
{
VkDebugReportCallbackCreateInfoEXT create_info={};
create_info.sType=VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
create_info.pNext=nullptr;
2019-04-20 16:24:11 +08:00
create_info.flags=VK_DEBUG_REPORT_ERROR_BIT_EXT|VK_DEBUG_REPORT_WARNING_BIT_EXT|VK_DEBUG_REPORT_DEBUG_BIT_EXT|VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
create_info.pfnCallback=dbgFunc;
create_info.pUserData=nullptr;
CreateDebugReportCallbackEXT(inst,&create_info,nullptr,&debug_report_callback);
}
debug_messenger=nullptr;
{
VkDebugUtilsMessengerCreateInfoEXT createInfo={};
createInfo.sType=VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
createInfo.messageSeverity=VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT|VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT|VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
createInfo.messageType=VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT|VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT|VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
createInfo.pfnUserCallback=debugCallback;
CreateDebugUtilsMessengerEXT(inst,&createInfo,nullptr,&debug_messenger);
}
uint32_t gpu_count = 1;
2019-04-09 00:22:26 +08:00
if(vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr)==VK_SUCCESS)
2019-04-09 00:22:26 +08:00
{
VkPhysicalDevice *pd_list=new VkPhysicalDevice[gpu_count];
vkEnumeratePhysicalDevices(inst, &gpu_count,pd_list);
for(uint32_t i=0;i<gpu_count;i++)
physical_devices.Add(new PhysicalDevice(inst,pd_list[i]));
2019-04-19 16:32:54 +08:00
delete[] pd_list;
}
}
Instance::~Instance()
{
physical_devices.Clear();
if(debug_messenger)
DestroyDebugUtilsMessengerEXT(inst,debug_messenger,nullptr);
if(debug_report_callback)
DestroyDebugReportCallbackEXT(inst,debug_report_callback,nullptr);
vkDestroyInstance(inst,nullptr);
2019-04-09 00:22:26 +08:00
}
const bool Instance::CheckLayerSupport(const UTF8String &layer_name)const
{
const uint32_t count=layer_properties.GetCount();
VkLayerProperties *lp=layer_properties.GetData();
for(uint32_t i=0;i<count;i++)
{
if(layer_name==lp->layerName)
return(true);
++lp;
}
return(false);
}
const PhysicalDevice *Instance::GetDevice(VkPhysicalDeviceType type)const
{
const uint32_t count=physical_devices.GetCount();
PhysicalDevice **pd=physical_devices.GetData();
for(uint32_t i=0;i<count;i++)
{
if((*pd)->GetDeviceType()==type)
return(*pd);
++pd;
}
return(nullptr);
}
2019-04-18 16:06:44 +08:00
Device *Instance::CreateRenderDevice(Window *win,const PhysicalDevice *pd)
2019-04-10 14:00:06 +08:00
{
if(!win)
return(nullptr);
if(!pd)pd=GetDevice(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU); //先找独显
if(!pd)pd=GetDevice(VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU); //再找集显
if(!pd)pd=GetDevice(VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU); //最后找虚拟显卡
if(!pd)
2019-04-10 23:31:24 +08:00
return(nullptr);
2019-04-20 00:51:03 +08:00
2019-04-18 16:06:44 +08:00
return VK_NAMESPACE::CreateRenderDevice(inst,pd,win);
2019-04-10 14:00:06 +08:00
}
2019-04-09 00:22:26 +08:00
VK_NAMESPACE_END