|
46 | 46 | # include "FileSystem.hpp" |
47 | 47 | #endif |
48 | 48 |
|
| 49 | +#if DILIGENT_USE_OPENXR |
| 50 | +# define XR_USE_GRAPHICS_API_VULKAN |
| 51 | +# include <openxr/openxr_platform.h> |
| 52 | +#endif |
| 53 | + |
49 | 54 | namespace Diligent |
50 | 55 | { |
51 | 56 | namespace |
@@ -620,6 +625,43 @@ void EngineFactoryVkImpl::EnumerateAdapters(Version MinVersion, |
620 | 625 | } |
621 | 626 | } |
622 | 627 |
|
| 628 | +#if DILIGENT_USE_OPENXR |
| 629 | +VkResult CreateVulkanDeviceForOpenXR(const OpenXRAttribs& XRAttribs, |
| 630 | + VkPhysicalDevice PhysicalDevice, |
| 631 | + const VkDeviceCreateInfo* pCreateInfo, |
| 632 | + const VkAllocationCallbacks* pAllocator, |
| 633 | + VkDevice* pDevice) noexcept(false) |
| 634 | +{ |
| 635 | + XrInstance xrInstance = XR_NULL_HANDLE; |
| 636 | + static_assert(sizeof(XrInstance) == sizeof(XRAttribs.Instance), "XrInstance size mismatch"); |
| 637 | + memcpy(&xrInstance, &XRAttribs.Instance, sizeof(XrInstance)); |
| 638 | + |
| 639 | + PFN_xrGetInstanceProcAddr xrGetInstanceProcAddr = reinterpret_cast<PFN_xrGetInstanceProcAddr>(XRAttribs.GetInstanceProcAddr); |
| 640 | + PFN_xrCreateVulkanDeviceKHR xrCreateVulkanDeviceKHR = nullptr; |
| 641 | + if (XR_FAILED(xrGetInstanceProcAddr(xrInstance, "xrCreateVulkanDeviceKHR", reinterpret_cast<PFN_xrVoidFunction*>(&xrCreateVulkanDeviceKHR)))) |
| 642 | + { |
| 643 | + LOG_ERROR_AND_THROW("Failed to get xrCreateVulkanDeviceKHR function"); |
| 644 | + } |
| 645 | + VERIFY_EXPR(xrCreateVulkanDeviceKHR != nullptr); |
| 646 | + |
| 647 | + XrVulkanDeviceCreateInfoKHR VulkanDeviceCI{XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR}; |
| 648 | + static_assert(sizeof(VulkanDeviceCI.systemId) == sizeof(XRAttribs.SystemId), "systemId size mismatch"); |
| 649 | + memcpy(&VulkanDeviceCI.systemId, &XRAttribs.SystemId, sizeof(VulkanDeviceCI.systemId)); |
| 650 | + VulkanDeviceCI.createFlags = 0; |
| 651 | + VulkanDeviceCI.pfnGetInstanceProcAddr = vkGetInstanceProcAddr; |
| 652 | + VulkanDeviceCI.vulkanPhysicalDevice = PhysicalDevice; |
| 653 | + VulkanDeviceCI.vulkanCreateInfo = pCreateInfo; |
| 654 | + VulkanDeviceCI.vulkanAllocator = pAllocator; |
| 655 | + |
| 656 | + VkResult vkRes = VK_ERROR_UNKNOWN; |
| 657 | + if (XR_FAILED(xrCreateVulkanDeviceKHR(xrInstance, &VulkanDeviceCI, pDevice, &vkRes))) |
| 658 | + { |
| 659 | + LOG_ERROR_AND_THROW("Failed to create Vulkan device for OpenXR"); |
| 660 | + } |
| 661 | + return vkRes; |
| 662 | +} |
| 663 | +#endif |
| 664 | + |
623 | 665 | void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& EngineCI, |
624 | 666 | IRenderDevice** ppDevice, |
625 | 667 | IDeviceContext** ppContexts) |
@@ -664,10 +706,34 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& En |
664 | 706 | InstanceCI.IgnoreDebugMessageCount = EngineCI.IgnoreDebugMessageCount; |
665 | 707 | InstanceCI.ppIgnoreDebugMessageNames = EngineCI.ppIgnoreDebugMessageNames; |
666 | 708 |
|
| 709 | +#if DILIGENT_USE_OPENXR |
| 710 | + if (EngineCI.pXRAttribs != nullptr && EngineCI.pXRAttribs->Instance != 0) |
| 711 | + { |
| 712 | + InstanceCI.XR.Instance = EngineCI.pXRAttribs->Instance; |
| 713 | + InstanceCI.XR.SystemId = EngineCI.pXRAttribs->SystemId; |
| 714 | + InstanceCI.XR.GetInstanceProcAddr = EngineCI.pXRAttribs->GetInstanceProcAddr; |
| 715 | + } |
| 716 | +#endif |
| 717 | + |
667 | 718 | auto Instance = VulkanUtilities::VulkanInstance::Create(InstanceCI); |
668 | 719 |
|
669 | | - auto vkDevice = Instance->SelectPhysicalDevice(EngineCI.AdapterId); |
670 | | - auto PhysicalDevice = VulkanUtilities::VulkanPhysicalDevice::Create({*Instance, vkDevice, /*LogExtensions = */ true}); |
| 720 | + VkPhysicalDevice vkPhysDevice = VK_NULL_HANDLE; |
| 721 | +#if DILIGENT_USE_OPENXR |
| 722 | + if (InstanceCI.XR.Instance != 0) |
| 723 | + { |
| 724 | + if (EngineCI.AdapterId != DEFAULT_ADAPTER_ID) |
| 725 | + { |
| 726 | + LOG_WARNING_MESSAGE("AdapterId is ignored when OpenXR is used as the physical device is selected by OpenXR runtime"); |
| 727 | + } |
| 728 | + vkPhysDevice = Instance->SelectPhysicalDeviceForOpenXR(InstanceCI.XR); |
| 729 | + } |
| 730 | + else |
| 731 | +#endif |
| 732 | + { |
| 733 | + vkPhysDevice = Instance->SelectPhysicalDevice(EngineCI.AdapterId); |
| 734 | + } |
| 735 | + |
| 736 | + auto PhysicalDevice = VulkanUtilities::VulkanPhysicalDevice::Create({*Instance, vkPhysDevice, /*LogExtensions = */ true}); |
671 | 737 |
|
672 | 738 | std::vector<const char*> DeviceExtensions; |
673 | 739 | if (Instance->IsExtensionEnabled(VK_KHR_SURFACE_EXTENSION_NAME)) |
@@ -1199,8 +1265,28 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& En |
1199 | 1265 | vkDeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions.empty() ? nullptr : DeviceExtensions.data(); |
1200 | 1266 | vkDeviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(DeviceExtensions.size()); |
1201 | 1267 |
|
1202 | | - auto vkAllocator = Instance->GetVkAllocator(); |
1203 | | - auto LogicalDevice = VulkanUtilities::VulkanLogicalDevice::Create(*PhysicalDevice, vkDeviceCreateInfo, EnabledExtFeats, vkAllocator); |
| 1268 | + VkAllocationCallbacks* vkAllocator = Instance->GetVkAllocator(); |
| 1269 | + VkDevice vkDevice = VK_NULL_HANDLE; |
| 1270 | + VkResult vkRes = VK_ERROR_UNKNOWN; |
| 1271 | +#if DILIGENT_USE_OPENXR |
| 1272 | + if (InstanceCI.XR.Instance != 0) |
| 1273 | + { |
| 1274 | + vkRes = CreateVulkanDeviceForOpenXR(*EngineCI.pXRAttribs, PhysicalDevice->GetVkDeviceHandle(), &vkDeviceCreateInfo, vkAllocator, &vkDevice); |
| 1275 | + } |
| 1276 | + else |
| 1277 | +#endif |
| 1278 | + { |
| 1279 | + vkRes = vkCreateDevice(PhysicalDevice->GetVkDeviceHandle(), &vkDeviceCreateInfo, vkAllocator, &vkDevice); |
| 1280 | + } |
| 1281 | + CHECK_VK_ERROR_AND_THROW(vkRes, "Failed to create logical device"); |
| 1282 | + |
| 1283 | + auto LogicalDevice = VulkanUtilities::VulkanLogicalDevice::Create({ |
| 1284 | + *PhysicalDevice, |
| 1285 | + vkDevice, |
| 1286 | + *vkDeviceCreateInfo.pEnabledFeatures, |
| 1287 | + EnabledExtFeats, |
| 1288 | + vkAllocator, |
| 1289 | + }); |
1204 | 1290 |
|
1205 | 1291 | auto& RawMemAllocator = GetRawAllocator(); |
1206 | 1292 |
|
|
0 commit comments