18 #define LUG_INIT_GRAPHICS_MODULES_REQUIREMENTS(name) \ 20 Module::Type::name, ::lug::Graphics::Vulkan::Requirements::name::requirements \ 25 #undef LUG_INIT_GRAPHICS_MODULES_REQUIREMENTS 29 VkDebugReportFlagsEXT flags,
30 VkDebugReportObjectTypeEXT ,
34 const char* layerPrefix,
41 if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
42 level = System::Logger::Level::Error;
43 }
else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT || flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
44 level = System::Logger::Level::Warning;
45 }
else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
46 level = System::Logger::Level::Info;
47 }
else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
48 level = System::Logger::Level::Debug;
51 LUG_LOG.log(level,
"DebugReport: {}: {}", layerPrefix, msg);
74 auto vkDestroyDebugReportCallbackEXT =
_instance.
getProcAddr<PFN_vkDestroyDebugReportCallbackEXT>(
"vkDestroyDebugReportCallbackEXT");
76 if (vkDestroyDebugReportCallbackEXT) {
91 LUG_LOG.error(
"RendererVulkan: Can't init the instance");
100 if (static_cast<VkDevice>(
_device)) {
115 LUG_LOG.error(
"RendererVulkan: Can't init the device");
119 #if defined(LUG_DEBUG) 123 _resourceManager = std::make_unique<::lug::Graphics::ResourceManager>(*this);
129 VkResult result{VK_SUCCESS};
134 LUG_LOG.error(
"RendererVulkan: Can't load core vulkan functions");
143 uint32_t extensionsCount = 0;
144 result = vkEnumerateInstanceExtensionProperties(
nullptr, &extensionsCount,
nullptr);
146 if (result != VK_SUCCESS) {
147 LUG_LOG.error(
"RendererVulkan: Can't enumerate instance extensions: {}", result);
154 if (result != VK_SUCCESS) {
155 LUG_LOG.error(
"RendererVulkan: Can't enumerate instance extensions: {}", result);
162 uint32_t layersCount = 0;
163 result = vkEnumerateInstanceLayerProperties(&layersCount,
nullptr);
165 if (result != VK_SUCCESS) {
166 LUG_LOG.error(
"RendererVulkan: Can't enumerate instance layers: {}", result);
173 if (result != VK_SUCCESS) {
174 LUG_LOG.error(
"RendererVulkan: Can't enumerate instance layers: {}", result);
198 if (!instanceBuilder.build(
_instance, &result)) {
199 LUG_LOG.error(
"RendererVulkan: Can't create the instance: {}", result);
208 VkDebugReportCallbackCreateInfoEXT createInfo = {};
209 createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
211 createInfo.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT;
214 auto vkCreateDebugReportCallbackEXT =
_instance.
getProcAddr<PFN_vkCreateDebugReportCallbackEXT>(
"vkCreateDebugReportCallbackEXT");
216 if (vkCreateDebugReportCallbackEXT) {
219 LUG_LOG.warn(
"RendererVulkan: Can't load function vkCreateDebugReportCallbackEXT");
227 LUG_LOG.error(
"RendererVulkan: Can't load instance vulkan functions");
234 uint32_t physicalDevicesCount = 0;
235 result = vkEnumeratePhysicalDevices(static_cast<VkInstance>(
_instance), &physicalDevicesCount,
nullptr);
237 if (result != VK_SUCCESS) {
238 LUG_LOG.error(
"RendererVulkan: Can't enumerate physical devices: {}", result);
244 std::vector<VkPhysicalDevice> physicalDevices(physicalDevicesCount);
245 result = vkEnumeratePhysicalDevices(static_cast<VkInstance>(
_instance), &physicalDevicesCount, physicalDevices.data());
247 if (result != VK_SUCCESS) {
248 LUG_LOG.error(
"RendererVulkan: Can't enumerate physical devices: {}", result);
252 for (uint8_t idx = 0; idx < physicalDevicesCount; ++idx) {
260 uint32_t queueFamilyCount = 0;
261 vkGetPhysicalDeviceQueueFamilyProperties(physicalDevices[idx], &queueFamilyCount,
nullptr);
264 vkGetPhysicalDeviceQueueFamilyProperties(physicalDevices[idx], &queueFamilyCount,
_physicalDeviceInfos[idx].queueFamilies.data());
267 vkGetPhysicalDeviceMemoryProperties(physicalDevices[idx], &(
_physicalDeviceInfos[idx].memoryProperties));
271 uint32_t extensionsCount = 0;
272 result = vkEnumerateDeviceExtensionProperties(physicalDevices[idx],
nullptr, &extensionsCount,
nullptr);
274 if (result != VK_SUCCESS) {
275 LUG_LOG.error(
"RendererVulkan: Can't enumerate device extensions: {}", result);
280 result = vkEnumerateDeviceExtensionProperties(physicalDevices[idx],
nullptr, &extensionsCount,
_physicalDeviceInfos[idx].extensions.data());
282 if (result != VK_SUCCESS) {
283 LUG_LOG.error(
"RendererVulkan: Can't enumerate device extensions: {}", result);
290 #define LUG_LOAD_IMAGE_FORMAT_PROPERTIES(formatEnum) \ 291 vkGetPhysicalDeviceFormatProperties(physicalDevices[idx], formatEnum, &_physicalDeviceInfos[idx].formatProperties[formatEnum]); 293 #undef LUG_LOAD_IMAGE_FORMAT_PROPERTIES 304 VkResult result{VK_SUCCESS};
320 uint8_t matchedDeviceIdx = 0;
321 std::vector<uint8_t> matchedDevicesIdx{};
330 matchedDevicesIdx.push_back(idx);
334 if (matchedDevicesIdx.size() == 0) {
335 LUG_LOG.error(
"RendererVulkan: Can't find a compatible device");
340 matchedDeviceIdx = matchedDevicesIdx[0];
342 for (uint8_t idx : matchedDevicesIdx) {
344 matchedDeviceIdx = idx;
367 if (!deviceBuilder.
addQueues(VK_QUEUE_GRAPHICS_BIT, {
"queue_graphics"}) ||
368 !deviceBuilder.
addQueues(VK_QUEUE_TRANSFER_BIT, {
"queue_transfer"})) {
373 LUG_LOG.error(
"RendererVulkan: Can't create the device: {}", result);
381 LUG_LOG.error(
"RendererVulkan: Can't load device vulkan functions");
390 bool requirementsCheck =
true;
392 for (
const auto moduleType : modulesToCheck) {
395 std::vector<const char*> layers{};
396 std::vector<const char*> extensions{};
398 bool moduleRequirementsCheck =
true;
403 moduleRequirementsCheck = moduleRequirementsCheck && layersNotFound.size() == 0;
405 for (
const char*
const layerName : layersNotFound) {
406 LUG_LOG.warn(
"Can't load mandatory layer '{}' for module '{}'", layerName, moduleType);
413 for (
const char* layerName : layersNotFound) {
414 LUG_LOG.warn(
"Can't load optional layer '{}' for module '{}'", layerName, moduleType);
421 moduleRequirementsCheck = moduleRequirementsCheck && extensionsNotFound.size() == 0;
423 for (
const char*
const extensionName : extensionsNotFound) {
424 LUG_LOG.warn(
"Can't load mandatory extension '{}' for module '{}'", extensionName, moduleType);
431 for (
const char* extensionName : extensionsNotFound) {
432 LUG_LOG.warn(
"Can't load optional extension '{}' for module '{}'", extensionName, moduleType);
436 if (moduleRequirementsCheck) {
443 requirementsCheck = requirementsCheck && moduleRequirementsCheck;
446 return requirementsCheck;
450 bool requirementsCheck =
true;
452 for (
const auto moduleType : modulesToCheck) {
455 std::vector<const char*> extensions{};
456 VkPhysicalDeviceFeatures features{};
457 std::set<int8_t> queueFamiliesIdx{};
459 bool moduleRequirementsCheck =
true;
464 moduleRequirementsCheck = moduleRequirementsCheck && extensionsNotFound.size() == 0;
467 for (
const char*
const extensionName : extensionsNotFound) {
468 LUG_LOG.warn(
"Device {}: Can't load mandatory extension '{}' for module '{}'", physicalDeviceInfo.
properties.deviceName, extensionName, moduleType);
477 for (
const char* extensionName : extensionsNotFound) {
478 LUG_LOG.warn(
"Device {}: Can't load optional extension '{}' for module '{}'", physicalDeviceInfo.
properties.deviceName, extensionName, moduleType);
484 #define LUG_CHECK_VULKAN_PHYSICAL_DEVICE_MANDATORY_FEATURES(featureName) \ 486 if (requirements.mandatoryFeatures.featureName == VK_TRUE) { \ 487 if (physicalDeviceInfo.features.featureName == VK_TRUE) { \ 488 features.featureName = VK_TRUE; \ 491 LUG_LOG.warn("Device {}: Can't load mandatory feature '{}' for module '{}'", physicalDeviceInfo.properties.deviceName, #featureName, moduleType); \ 493 moduleRequirementsCheck = false; \ 498 #undef LUG_CHECK_VULKAN_PHYSICAL_DEVICE_MANDATORY_FEATURES 501 #define LUG_CHECK_VULKAN_PHYSICAL_DEVICE_OPTIONNAL_FEATURES(featureName) \ 503 if (requirements.optionalFeatures.featureName == VK_TRUE) { \ 504 if (physicalDeviceInfo.features.featureName == VK_TRUE) { \ 505 features.featureName = VK_TRUE; \ 506 } else if (!quiet) { \ 507 LUG_LOG.warn("Device {}: Can't load optional feature '{}' for module '{}'", physicalDeviceInfo.properties.deviceName, #featureName, moduleType); \ 512 #undef LUG_CHECK_VULKAN_PHYSICAL_DEVICE_MANDATORY_FEATURES 515 if (moduleRequirementsCheck) {
518 #define LUG_FILL_VULKAN_PHYSICAL_DEVICE_FEATURES(featureName) _loadedDeviceFeatures.featureName = _loadedDeviceFeatures.featureName || features.featureName; 520 #undef LUG_FILL_VULKAN_PHYSICAL_DEVICE_FEATURES 526 requirementsCheck = requirementsCheck && moduleRequirementsCheck;
529 return requirementsCheck;
532 template<
typename Info>
534 std::vector<const char*> layersNotFound{};
536 for (
const char* layerName : layers) {
537 if (info.containsLayer(layerName)) {
538 layersFound.push_back(layerName);
540 layersNotFound.push_back(layerName);
544 return layersNotFound;
547 template<
typename Info>
549 std::vector<const char*> extensionsNotFound{};
551 for (
const char* extensionName : extensions) {
552 if (info.containsExtension(extensionName)) {
553 extensionsFound.push_back(extensionName);
555 extensionsNotFound.push_back(extensionName);
559 return extensionsNotFound;
579 return _window->beginFrame(elapsedTime);
587 for (
auto& renderView:
_window->getRenderViews()) {
588 if (!renderView->endFrame()) {
Stores the version of the Application.
#define LUG_INIT_GRAPHICS_MODULES_REQUIREMENTS(name)
const Renderer::Requirements requirements
void setExtensions(const std::vector< const char *> &extensions)
const std::vector< const char * > optionalInstanceExtensions
const std::vector< const char * > mandatoryInstanceLayers
PhysicalDeviceInfo * device
::lug::Graphics::Render::Window * getWindow() override final
Function getProcAddr(const char *name) const
const std::vector< const char * > optionalDeviceExtensions
bool endFrame() override final
static VKAPI_ATTR VkBool32 VKAPI_CALL debugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char *layerPrefix, const char *msg, void *)
static const std::unordered_map< Module::Type, Requirements > modulesRequirements
#define LUG_VERSION_MAJOR
uint8_t addQueues(VkQueueFlags queueFlags, const std::vector< std::string > &queuesNames)
std::vector< VkExtensionProperties > extensions
std::vector< const char * > checkRequirementsLayers(const Info &info, const std::vector< const char *> &layers, std::vector< const char *> &layersFound)
std::vector< const char * > _loadedInstanceExtensions
static std::unique_ptr< Window > create(lug::Graphics::Vulkan::Renderer &renderer, Window::InitInfo &initInfo)
std::vector< const char * > _loadedInstanceLayers
bool beginInit(const std::string &appName, const Core::Version &appVersion, const Renderer::InitInfo &initInfo) override final
bool initInstance(const std::string &appName, const Core::Version &appVersion)
const std::set< Module::Type > & getLoadedMandatoryModules() const
bool beginFrame(const lug::System::Time &elapsedTime) override final
std::unordered_map< Render::Pipeline::Id, Resource::WeakPtr< Render::Pipeline > > _pipelines
void setApplicationInfo(const std::string &name, const Core::Version &version={0, 0, 0})
const std::vector< const char * > mandatoryDeviceExtensions
bool build(API::Device &device, VkResult *returnResult=nullptr)
#define LUG_CHECK_VULKAN_PHYSICAL_DEVICE_MANDATORY_FEATURES(featureName)
bool loadInstanceFunctions(const Instance &instance)
#define LUG_VULKAN_FORMAT(macro)
bool isInstanceExtensionLoaded(const char *name) const
VkDebugReportCallbackEXT _debugReportCallback
#define LUG_GRAPHICS_MODULES(macro)
std::unique_ptr< Render::Window > _window
Renderer(Graphics &graphics)
#define LUG_VERSION_PATCH
bool loadDeviceFunctions(const Device &device)
VkPhysicalDeviceFeatures _loadedDeviceFeatures
std::unique_ptr< ResourceManager > _resourceManager
std::vector< PhysicalDeviceInfo > _physicalDeviceInfos
bool checkRequirementsDevice(const PhysicalDeviceInfo &physicalDeviceInfo, const std::set< Module::Type > &modulesToCheck, bool finalization, bool quiet)
void setFeatures(VkPhysicalDeviceFeatures features)
#define LUG_VULKAN_PHYSICAL_DEVICE_FEATURES(macro)
bool checkRequirementsInstance(const std::set< Module::Type > &modulesToCheck)
const std::vector< const char * > optionalInstanceLayers
std::vector< const char * > checkRequirementsExtensions(const Info &info, const std::vector< const char *> &extensions, std::vector< const char *> &extensionsFound)
const std::vector< const char * > mandatoryInstanceExtensions
#define LUG_VERSION_MINOR
#define LUG_CHECK_VULKAN_PHYSICAL_DEVICE_OPTIONNAL_FEATURES(featureName)
#define LUG_FILL_VULKAN_PHYSICAL_DEVICE_FEATURES(featureName)
std::vector< const char * > _loadedDeviceExtensions
const std::set< Module::Type > & getLoadedOptionalModules() const
void unsupportedModule(Module::Type type)
#define LUG_LOAD_IMAGE_FORMAT_PROPERTIES(formatEnum)
::lug::Graphics::Render::Window * createWindow(Render::Window::InitInfo &initInfo) override final
VkPhysicalDeviceProperties properties
std::vector< VkLayerProperties > layers
bool finishInit() override final
InstanceInfo _instanceInfo
PhysicalDeviceInfo * _physicalDeviceInfo