99 XrVulkanGraphicsDeviceGetInfoKHR xrVulkanGraphicsDeviceGetInfo{
100 .type = XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR,
107 PLOGI <<
"Picked vulkan graphics device";
114 uint32_t deviceExtensionCount;
115 PLOG_FN_VK(vkEnumerateDeviceExtensionProperties(
vkPhysicalDevice,
nullptr, &deviceExtensionCount,
nullptr));
122 PLOGV <<
"Device Extension: " << extension.extensionName;
129#if !defined(HEADLESS) && !defined(COMPUTE_DEBUG)
148 bool isExtensionSupported =
false;
151 if ( strcmp( extensionToEnable, supportedExtension.extensionName ) == 0 )
153 isExtensionSupported =
true;
158 if ( !isExtensionSupported )
161 if ( strcmp( extensionToEnable, VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME ) == 0 ||
162 strcmp( extensionToEnable, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME ) == 0 )
164 PLOGW <<
"Optional Tracy extension " << extensionToEnable
165 <<
" not supported - Tracy will use standard profiling";
169 std::stringstream error;
170 error <<
"Required Vulkan device extension " << extensionToEnable <<
" is not supported!";
171 PLOGE << error.str();
172 throw std::runtime_error( error.str() );
180 VkPhysicalDeviceProperties physicalDeviceProperties;
188 const VkSampleCountFlags sampleCountFlags = physicalDeviceProperties.limits.framebufferColorSampleCounts & physicalDeviceProperties.limits.framebufferDepthSampleCounts;
190 if (sampleCountFlags & VK_SAMPLE_COUNT_4_BIT)
194 else if (sampleCountFlags & VK_SAMPLE_COUNT_2_BIT)
200 VkPhysicalDeviceFeatures physicalDeviceFeatures;
203 VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
205#if !defined(HEADLESS) && !defined(COMPUTE_DEBUG)
206 VkPhysicalDeviceFragmentShadingRateFeaturesKHR fragmentShadingRateFeatures{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR};
207 VkPhysicalDeviceMeshShaderFeaturesEXT meshShaderFeatures{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT};
209 VkPhysicalDeviceVulkan11Features vulkan11Features {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES};
210 VkPhysicalDeviceVulkan12Features vulkan12Features {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES};
211 VkPhysicalDeviceVulkan13Features vulkan13Features {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES};
212 VkPhysicalDeviceVulkan14Features vulkan14Features {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES};
213 VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT};
214 VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES};
218 .
add(physicalDeviceFeatures2)
219#if !defined(HEADLESS) && !defined(COMPUTE_DEBUG)
220 .
add(meshShaderFeatures)
221 .
add(fragmentShadingRateFeatures)
223 .
add(vulkan11Features)
224 .
add(vulkan12Features)
225 .
add(vulkan13Features)
226 .
add(vulkan14Features)
227 .
add(descriptorIndexingFeatures)
228 .
add(bufferDeviceAddressFeatures);
232#define VALIDATE_FEATURE(feature, is_not_supported_error) \
233 if (!feature) THROW_ERROR(is_not_supported_error); \
237 VALIDATE_FEATURE(vulkan11Features.shaderDrawParameters,
"Shader draw parameter not supported")
239 VALIDATE_FEATURE(vulkan12Features.descriptorIndexing,
"Descriptor indexing not supported")
240 VALIDATE_FEATURE(vulkan12Features.descriptorBindingPartiallyBound,
"Descriptor binding partially bound not supported")
241 VALIDATE_FEATURE(vulkan12Features.descriptorBindingVariableDescriptorCount,
"Descriptor variable descriptor count not supported")
242 VALIDATE_FEATURE(vulkan12Features.timelineSemaphore,
"timelineSemaphore is not supported!")
244 VALIDATE_FEATURE(vulkan13Features.maintenance4,
"maintenance4 is not supported")
245 VALIDATE_FEATURE(vulkan14Features.maintenance5,
"maintenance5 is not supported")
246 VALIDATE_FEATURE(vulkan14Features.maintenance6,
"maintenance6 is not supported")
247 VALIDATE_FEATURE(vulkan13Features.synchronization2,
"Synchronization2 not supported")
249 VALIDATE_FEATURE( descriptorIndexingFeatures.runtimeDescriptorArray,
"Descriptor indexing not supported" )
250 VALIDATE_FEATURE( descriptorIndexingFeatures.shaderStorageBufferArrayNonUniformIndexing,
"Shader storage buffer array non uniform indexing not supported" )
252 VALIDATE_FEATURE( bufferDeviceAddressFeatures.bufferDeviceAddress,
"Buffer device addresses are not supported" )
254#if !defined(HEADLESS) && !defined(COMPUTE_DEBUG)
255 VALIDATE_FEATURE(physicalDeviceFeatures2.features.shaderStorageImageMultisample,
"Shader storage image multisample is not supported")
257 VALIDATE_FEATURE(fragmentShadingRateFeatures.primitiveFragmentShadingRate,
"Primitive shading rate not supported")
259 VALIDATE_FEATURE(meshShaderFeatures.meshShader,
"meshShader is not supported")
260 VALIDATE_FEATURE(meshShaderFeatures.taskShader,
"taskShader is not supported")
261 VALIDATE_FEATURE(meshShaderFeatures.primitiveFragmentShadingRateMeshShader,
"primitiveFragmentShadingRateMeshShader is not supported")
262 VALIDATE_FEATURE(meshShaderFeatures.multiviewMeshShader,
"multiviewMeshShader is not supported")
265#undef VALIDATE_FEATURE
267 constexpr float queuePriority = 1.0f;
269 std::vector<VkDeviceQueueCreateInfo> deviceQueueCreateInfos;
271 VkDeviceQueueCreateInfo graphicsAndPresentDeviceQueueCreateInfo{
272 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
277 .pQueuePriorities = &queuePriority,
279 deviceQueueCreateInfos.push_back(graphicsAndPresentDeviceQueueCreateInfo);
283 graphicsAndPresentDeviceQueueCreateInfo.queueFamilyIndex =
queueFamily.present.index;
284 deviceQueueCreateInfos.push_back(graphicsAndPresentDeviceQueueCreateInfo);
287 VkDeviceQueueCreateInfo transferQueueDeviceQueueCreateInfo{
288 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
293 .pQueuePriorities = &queuePriority,
295 deviceQueueCreateInfos.push_back(transferQueueDeviceQueueCreateInfo);
297 VkDeviceCreateInfo deviceCreateInfo{
298 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
299 .pNext = &physicalDeviceFeatures2,
301 .queueCreateInfoCount =
static_cast<uint32_t
>(deviceQueueCreateInfos.size()),
302 .pQueueCreateInfos = deviceQueueCreateInfos.data(),
303 .enabledLayerCount = 0u,
304 .ppEnabledLayerNames =
nullptr,
307 .pEnabledFeatures =
nullptr
310 XrVulkanDeviceCreateInfoKHR vkDeviceCreateInfo{
311 .type = XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR,
315 .pfnGetInstanceProcAddr = vkGetInstanceProcAddr,
317 .vulkanCreateInfo = &deviceCreateInfo,
318 .vulkanAllocator =
nullptr
325 VkResult deviceCreationResult{};
327 if (deviceCreationResult != VK_SUCCESS)
329 THROW_ERROR(
"Failed to create a vulkan device");
332 PLOGI <<
"Device Created!";
336 VkPhysicalDeviceProperties2 deviceProps2 {
337 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
340#if !defined(HEADLESS) && !defined(COMPUTE_DEBUG)
341 VkPhysicalDeviceMeshShaderPropertiesEXT meshShaderProps {
342 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_EXT
347 builder.
add(deviceProps2)
348#if !defined(HEADLESS) && !defined(COMPUTE_DEBUG)
349 .
add(meshShaderProps)
356#if !defined(HEADLESS) && !defined(COMPUTE_DEBUG)
359 PLOGV <<
"=== Mesh Shader Properties ===";
360 PLOGV <<
"Max Task WorkGroup Total Count: " << meshShaderProps.maxTaskWorkGroupTotalCount;
361 PLOGV <<
"Max Task WorkGroup Count: ("
362 << meshShaderProps.maxTaskWorkGroupCount[0] <<
", "
363 << meshShaderProps.maxTaskWorkGroupCount[1] <<
", "
364 << meshShaderProps.maxTaskWorkGroupCount[2] <<
")";
365 PLOGV <<
"Max Task WorkGroup Invocations: " << meshShaderProps.maxTaskWorkGroupInvocations;
366 PLOGV <<
"Max Task WorkGroup Size: ("
367 << meshShaderProps.maxTaskWorkGroupSize[0] <<
", "
368 << meshShaderProps.maxTaskWorkGroupSize[1] <<
", "
369 << meshShaderProps.maxTaskWorkGroupSize[2] <<
")";
370 PLOGV <<
"Max Task Payload Size: " << meshShaderProps.maxTaskPayloadSize;
371 PLOGV <<
"Max Task Shared Memory Size: " << meshShaderProps.maxTaskSharedMemorySize;
372 PLOGV <<
"Max Task Payload and Shared Memory Size: " << meshShaderProps.maxTaskPayloadAndSharedMemorySize;
376 PLOGV <<
"Max Mesh WorkGroup Total Count: " << meshShaderProps.maxMeshWorkGroupTotalCount;
377 PLOGV <<
"Max Mesh WorkGroup Count: ("
378 << meshShaderProps.maxMeshWorkGroupCount[0] <<
", "
379 << meshShaderProps.maxMeshWorkGroupCount[1] <<
", "
380 << meshShaderProps.maxMeshWorkGroupCount[2] <<
")";
381 PLOGV <<
"Max Mesh WorkGroup Invocations: " << meshShaderProps.maxMeshWorkGroupInvocations;
382 PLOGV <<
"Max Mesh WorkGroup Size: ("
383 << meshShaderProps.maxMeshWorkGroupSize[0] <<
", "
384 << meshShaderProps.maxMeshWorkGroupSize[1] <<
", "
385 << meshShaderProps.maxMeshWorkGroupSize[2] <<
")";
386 PLOGV <<
"Max Mesh Shared Memory Size: " << meshShaderProps.maxMeshSharedMemorySize;
387 PLOGV <<
"Max Mesh Payload and Output Memory Size: " << meshShaderProps.maxMeshPayloadAndOutputMemorySize;
391 PLOGV <<
"Max Mesh Output Memory Size: " << meshShaderProps.maxMeshOutputMemorySize;
392 PLOGV <<
"Max Mesh Output Components: " << meshShaderProps.maxMeshOutputComponents;
393 PLOGV <<
"Max Mesh Output Vertices: " << meshShaderProps.maxMeshOutputVertices;
394 PLOGV <<
"Max Mesh Output Primitives: " << meshShaderProps.maxMeshOutputPrimitives;
395 PLOGV <<
"Max Mesh Output Layers: " << meshShaderProps.maxMeshOutputLayers;
396 PLOGV <<
"Max Mesh Multiview View Count: " << meshShaderProps.maxMeshMultiviewViewCount;
399 PLOGV <<
"Mesh Output Per Vertex Granularity: " << meshShaderProps.meshOutputPerVertexGranularity;
400 PLOGV <<
"Mesh Output Per Primitive Granularity: " << meshShaderProps.meshOutputPerPrimitiveGranularity;
403 PLOGV <<
"Max Preferred Task WorkGroup Invocations: " << meshShaderProps.maxPreferredTaskWorkGroupInvocations;
404 PLOGV <<
"Max Preferred Mesh WorkGroup Invocations: " << meshShaderProps.maxPreferredMeshWorkGroupInvocations;
405 PLOGV <<
"Prefers Local Invocation Vertex Output: " << (meshShaderProps.prefersLocalInvocationVertexOutput ?
"Yes" :
"No");
406 PLOGV <<
"Prefers Local Invocation Primitive Output: " << (meshShaderProps.prefersLocalInvocationPrimitiveOutput ?
"Yes" :
"No");
407 PLOGV <<
"Prefers Compact Vertex Output: " << (meshShaderProps.prefersCompactVertexOutput ?
"Yes" :
"No");
408 PLOGV <<
"Prefers Compact Primitive Output: " << (meshShaderProps.prefersCompactPrimitiveOutput ?
"Yes" :
"No");
414 VkDeviceQueueInfo2 drawQueueInfo = {
415 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
424 PLOGI <<
"Retrieved draw queue";
426 VkDeviceQueueInfo2 presentQueueInfo {
427 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
436 PLOGI <<
"Retrieved present queue";
438 VkDeviceQueueInfo2 transferQueueInfo {
439 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
448 PLOGI <<
"Retrieved transfer queue";
454 VmaAllocatorCreateInfo allocatorCI{};
458 allocatorCI.vulkanApiVersion = VK_API_VERSION_1_3;
460 if (vmaCreateAllocator(&allocatorCI, &
vmaAllocator_) != VK_SUCCESS)
462 throw std::runtime_error(
"Failed to create VMA allocator");
464 PLOGI <<
"VMA allocator created";
469 uint32_t& outGraphicsIndex,
470 uint32_t& outPresentIndex,
471 uint32_t& outTransferIndex)
473 std::optional<uint32_t> graphicsIndex;
474 std::optional<uint32_t> presentIndex;
475 std::optional<uint32_t> dedicatedTransferIndex;
476 std::optional<uint32_t> fallbackTransferIndex;
478 uint32_t queueFamilyCount = 0;
479 vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount,
nullptr);
480 if (queueFamilyCount == 0) {
481 throw std::runtime_error(
"Physical device has no queue families!");
484 std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
485 vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilies.data());
487 PLOGI <<
"Found " << queueFamilyCount <<
" queue families.";
489 for (uint32_t i = 0; i < queueFamilyCount; ++i) {
490 const auto& props = queueFamilies[i];
491 PLOGI <<
"Family " << i <<
": count=" << props.queueCount <<
", flags=" << std::hex << props.queueFlags;
493 if (props.queueCount == 0) {
498 if (props.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
499 if (!graphicsIndex.has_value()) {
501 PLOGI <<
" Found potential Graphics Queue Family: " << i;
504 if (props.queueFlags & VK_QUEUE_TRANSFER_BIT) {
505 if (!fallbackTransferIndex.has_value()) {
506 fallbackTransferIndex = i;
507 PLOGI <<
" Marking as Fallback Transfer Queue Family: " << i;
513 if (props.queueFlags & VK_QUEUE_TRANSFER_BIT) {
515 if (!(props.queueFlags & VK_QUEUE_GRAPHICS_BIT)) {
516 if (!dedicatedTransferIndex.has_value()) {
517 dedicatedTransferIndex = i;
518 PLOGI <<
" Found potential *Dedicated* Transfer Queue Family: " << i;
528 VkBool32 presentSupport = VK_FALSE;
529 VkResult presentCheckResult = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, surface, &presentSupport);
530 if (presentCheckResult == VK_SUCCESS && presentSupport) {
531 if (!presentIndex.has_value()) {
533 PLOGI <<
" Found potential Present Queue Family: " << i;
535 }
else if (presentCheckResult != VK_SUCCESS) {
536 PLOGW <<
" vkGetPhysicalDeviceSurfaceSupportKHR failed for family " << i <<
" with error: " << presentCheckResult;
543 if (!graphicsIndex.has_value()) {
544 throw std::runtime_error(
"Failed to find a suitable Graphics queue family!");
546 outGraphicsIndex = graphicsIndex.value();
547 PLOGI <<
"Selected Graphics Queue Family Index: " << outGraphicsIndex;
550 if (!presentIndex.has_value()) {
553 VkBool32 presentSupport = VK_FALSE;
554 vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, outGraphicsIndex, surface, &presentSupport);
556 presentIndex = outGraphicsIndex;
557 PLOGI <<
" No dedicated Present Queue found, using Graphics Queue Family " << outGraphicsIndex <<
" for presentation.";
559 throw std::runtime_error(
"Failed to find a suitable Present queue family!");
562 outPresentIndex = presentIndex.value();
563 PLOGI <<
"Selected Present Queue Family Index: " << outPresentIndex;
567 if (dedicatedTransferIndex.has_value()) {
568 outTransferIndex = dedicatedTransferIndex.value();
569 PLOGI <<
"Selected *Dedicated* Transfer Queue Family Index: " << outTransferIndex;
570 }
else if (fallbackTransferIndex.has_value()) {
571 outTransferIndex = fallbackTransferIndex.value();
572 PLOGI <<
"Selected *Fallback* Transfer Queue Family Index (might be same as Graphics): " << outTransferIndex;
576 if (queueFamilies[outGraphicsIndex].queueFlags & VK_QUEUE_TRANSFER_BIT) {
577 outTransferIndex = outGraphicsIndex;
578 PLOGW <<
"No dedicated or distinct fallback Transfer Queue found. Using Graphics Queue Family " << outGraphicsIndex <<
" which supports transfer.";
580 throw std::runtime_error(
"Failed to find any queue family supporting Transfer operations, including the Graphics queue!");
584 PLOGI <<
"Final Queue Selection: Graphics=" << outGraphicsIndex <<
", Present=" << outPresentIndex <<
", Transfer=" << outTransferIndex;
587 if (outGraphicsIndex == outPresentIndex) PLOGI <<
"Note: Graphics and Present queues share the same family.";
588 if (outGraphicsIndex == outTransferIndex) PLOGI <<
"Note: Graphics and Transfer queues share the same family.";
589 if (outPresentIndex == outTransferIndex) PLOGI <<
"Note: Present and Transfer queues share the same family.";
674 const char* existingRuntime = std::getenv(
"XR_RUNTIME_JSON");
677 PLOGI <<
"[OpenXR Debug] XR_RUNTIME_JSON already set to: " << existingRuntime;
681 PLOGI <<
"[OpenXR Debug] XR_RUNTIME_JSON not set - OpenXR will search default locations";
684 if (customOpenXrRuntimePath.has_value())
686 PLOGI <<
"[OpenXR Debug] Using custom runtime path: " << customOpenXrRuntimePath.value().string();
688 std::cout <<
"Set openxr runtime environment varibale to " << customOpenXrRuntimePath.value().string().c_str();
689 _putenv_s(
"XR_RUNTIME_JSON", customOpenXrRuntimePath.value().string().c_str());
691 setenv(
"XR_RUNTIME_JSON", customOpenXrRuntimePath.value().string().c_str(), 1);
697 uint32_t instanceExtensionCount;
698 PLOG_FN_XR(xrEnumerateInstanceExtensionProperties(
nullptr, 0u, &instanceExtensionCount,
nullptr));
703 property.type = XR_TYPE_EXTENSION_PROPERTIES;
704 property.next =
nullptr;
709 PLOGI <<
"Found " << instanceExtensionCount <<
" XrInstance extensions";
714 uint32_t apiLayerCount = 0;
715 PLOG_FN_XR(xrEnumerateApiLayerProperties(0, &apiLayerCount,
nullptr));
720 PLOGI <<
"Creating OpenXR instance";
721 XrApplicationInfo applicationInfo{};
722 applicationInfo.apiVersion = XR_CURRENT_API_VERSION;
723 applicationInfo.applicationVersion =
static_cast<uint32_t
>(XR_MAKE_VERSION(0, 1, 0));
724 applicationInfo.engineVersion =
static_cast<uint32_t
>(XR_MAKE_VERSION(0, 1, 0));
726 std::string engineName =
"betonmischer";
727 std::string applicationName =
"VulkanSchnee";
729 memcpy(applicationInfo.engineName, engineName.data(), engineName.length() + 1u);
730 memcpy(applicationInfo.applicationName, applicationName.data(), applicationName.length() + 1u);
732 std::vector<const char*> extensions = {XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME};
736 extensions.push_back(XR_EXT_DEBUG_UTILS_EXTENSION_NAME);
744 PLOGV << supportedExtension.extensionName;
748 for (
const char* extension : extensions)
750 bool isInstanceExtensionSupported =
false;
753 if (strcmp(extension, supportedExtension.extensionName) == 0)
755 isInstanceExtensionSupported =
true;
760 if (!isInstanceExtensionSupported)
762 std::stringstream error;
763 error <<
"OpenXr Instance Extension " << extension <<
" is not supported!";
764 PLOGE <<
"[OpenXR Debug] " << error.str();
765 PLOGE <<
"[OpenXR Debug] This usually means no OpenXR runtime is installed or running.";
766 PLOGE <<
"[OpenXR Debug] For SteamVR: ensure SteamVR is running";
767 PLOGE <<
"[OpenXR Debug] For Monado: check ~/.config/openxr/1/active_runtime.json exists";
774 std::vector<std::string> requrestedApiLayers = {
"XR_APILAYER_LUNARG_core_validation"};
775 std::vector<const char*> enabledLayers = {};
777 for (
auto& requestedLayer : requrestedApiLayers)
782 if (strcmp(requestedLayer.c_str(), layerProperty.layerName) != 0)
788 enabledLayers.push_back(layerProperty.layerName);
789 PLOGI <<
"Enabled: " << layerProperty.layerName;
795 XrInstanceCreateInfo instanceCreateInfo{
796 .type = XR_TYPE_INSTANCE_CREATE_INFO,
799 .applicationInfo = applicationInfo,
800 .enabledApiLayerCount =
static_cast<uint32_t
>(enabledLayers.size()),
801 .enabledApiLayerNames = enabledLayers.data(),
802 .enabledExtensionCount =
static_cast<uint32_t
>(extensions.size()),
803 .enabledExtensionNames = extensions.data()
805 XrResult instanceCreationResult = xrCreateInstance(&instanceCreateInfo, &
xrInstance);
806 if (instanceCreationResult != XR_SUCCESS)
808 if (instanceCreationResult == XR_ERROR_RUNTIME_FAILURE)
812 THROW_XR_ERROR(instanceCreationResult);
814 if (instanceCreationResult == XR_ERROR_RUNTIME_UNAVAILABLE)
820 PLOGI <<
"OpenXR instance created successfully.";
1021#if !defined(HEADLESS) && !defined(COMPUTE_DEBUG)
1025 VkApplicationInfo appInfo = {
1026 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
1028 .pApplicationName =
"vulkan_schnee",
1029 .applicationVersion = VK_MAKE_VERSION(0, 1, 0),
1030 .pEngineName =
"No Engine",
1031 .engineVersion = VK_MAKE_VERSION(0, 1, 0),
1032 .apiVersion = VK_API_VERSION_1_4,
1035 std::vector<VkValidationFeatureEnableEXT> enabledValidationFeatures;
1036 std::vector<VkValidationFeatureDisableEXT> disabledValidationFeatures;
1042 PLOGI <<
"Starting with GPU debuggin mode None";
1044 disabledValidationFeatures.push_back(VK_VALIDATION_FEATURE_DISABLE_ALL_EXT);
1049 PLOGI <<
"Starting GPU debugging mode GPU printf";
1050 enabledValidationFeatures = {
1051 VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT
1057 PLOGI <<
"Starting GPU debugging mode GPU validation";
1058 enabledValidationFeatures = {
1059 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
1060 VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
1061 VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
1062 VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT
1068 VkValidationFeaturesEXT validationFeatures {
1069 .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
1071 .enabledValidationFeatureCount =
static_cast<uint32_t
>(enabledValidationFeatures.size()),
1072 .pEnabledValidationFeatures = enabledValidationFeatures.data(),
1073 .disabledValidationFeatureCount =
static_cast<uint32_t
>(disabledValidationFeatures.size()),
1074 .pDisabledValidationFeatures = disabledValidationFeatures.data()
1077 VkInstanceCreateInfo createInfo = {
1078 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
1079 .pNext = &validationFeatures,
1081 .pApplicationInfo = &appInfo,
1082 .enabledLayerCount = 0u,
1083 .ppEnabledLayerNames =
nullptr,
1091 constexpr std::array layers = {
1092 "VK_LAYER_KHRONOS_validation",
1099 std::vector<VkLayerProperties> supportedInstanceLayers;
1100 uint32_t instanceLayerCount;
1101 PLOG_FN_VK(vkEnumerateInstanceLayerProperties(&instanceLayerCount,
nullptr));
1102 supportedInstanceLayers.resize(instanceLayerCount);
1103 PLOG_FN_VK(vkEnumerateInstanceLayerProperties(&instanceLayerCount, supportedInstanceLayers.data()));
1110 for (
const char* layer : layers)
1112 bool isLayerSupported =
false;
1113 for (
const VkLayerProperties& supportedLayer : supportedInstanceLayers)
1115 PLOGI << supportedLayer.layerName <<
" " << supportedLayer.description;
1116 if (strcmp(layer, supportedLayer.layerName) == 0)
1118 PLOGI <<
"Layer is supported!";
1119 isLayerSupported =
true;
1124 if (!isLayerSupported)
1126 std::stringstream error;
1127 error <<
"Vulkan instance layer " << layer <<
" is not supported!";
1128 PLOGE << error.str();
1129 throw std::runtime_error(error.str());
1133 createInfo.enabledLayerCount =
static_cast<uint32_t
>(layers.size());
1134 createInfo.ppEnabledLayerNames = layers.data();
1138 XrVulkanInstanceCreateInfoKHR createInfoXr = {};
1139 createInfoXr.type = XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR;
1140 createInfoXr.next =
nullptr;
1141 createInfoXr.vulkanCreateInfo = &createInfo;
1142 createInfoXr.vulkanAllocator =
nullptr;
1144 createInfoXr.createFlags = 0;
1145 createInfoXr.pfnGetInstanceProcAddr = vkGetInstanceProcAddr;
1151 if (xrResult != XR_SUCCESS)
1153 throw std::runtime_error(
"XrFunctionCall: Failed to create Vulkan instance with error code: " + std::to_string(xrResult));
1155 if (result != VK_SUCCESS)
1157 throw std::runtime_error(
"VulkanResult: Failed to create Vulkan instance with error code: " + std::to_string(result));
1161 PLOGI <<
"Created Vulkan Instance";