瀏覽代碼

Merge remote-tracking branch 'XR/main' into initial-xr

byrcolin 3 年之前
父節點
當前提交
4dfb8e5f0b
共有 68 個文件被更改,包括 2101 次插入0 次删除
  1. 11 0
      Gems/XR/3rdParty/Platform/Android/BuiltInPackages_android.cmake
  2. 11 0
      Gems/XR/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake
  3. 10 0
      Gems/XR/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake
  4. 10 0
      Gems/XR/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake
  5. 10 0
      Gems/XR/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake
  6. 17 0
      Gems/XR/CMakeLists.txt
  7. 77 0
      Gems/XR/Code/CMakeLists.txt
  8. 13 0
      Gems/XR/Code/Include/XR/Platform/Android/XR_Android.h
  9. 9 0
      Gems/XR/Code/Include/XR/Platform/Android/XR_Platform.h
  10. 12 0
      Gems/XR/Code/Include/XR/Platform/Android/platform_private_android_files.cmake
  11. 14 0
      Gems/XR/Code/Include/XR/Platform/Linux/XR_Linux.h
  12. 10 0
      Gems/XR/Code/Include/XR/Platform/Linux/XR_Platform.h
  13. 11 0
      Gems/XR/Code/Include/XR/Platform/Linux/platform_private_linux_files.cmake
  14. 13 0
      Gems/XR/Code/Include/XR/Platform/Mac/XR_Mac.h
  15. 9 0
      Gems/XR/Code/Include/XR/Platform/Mac/XR_Platform.h
  16. 10 0
      Gems/XR/Code/Include/XR/Platform/Mac/platform_private_mac_files.cmake
  17. 9 0
      Gems/XR/Code/Include/XR/Platform/Windows/XR_Platform.h
  18. 12 0
      Gems/XR/Code/Include/XR/Platform/Windows/XR_Windows.h
  19. 12 0
      Gems/XR/Code/Include/XR/Platform/Windows/platform_private_windows_files.cmake
  20. 10 0
      Gems/XR/Code/Include/XR/Platform/iOS/XR_Platform.h
  21. 10 0
      Gems/XR/Code/Include/XR/Platform/iOS/platform_private_ios_files.cmake
  22. 38 0
      Gems/XR/Code/Include/XR/XRBase.h
  23. 100 0
      Gems/XR/Code/Include/XR/XRDevice.h
  24. 77 0
      Gems/XR/Code/Include/XR/XRFactory.h
  25. 55 0
      Gems/XR/Code/Include/XR/XRInput.h
  26. 59 0
      Gems/XR/Code/Include/XR/XRInstance.h
  27. 77 0
      Gems/XR/Code/Include/XR/XRObject.h
  28. 98 0
      Gems/XR/Code/Include/XR/XRSession.h
  29. 46 0
      Gems/XR/Code/Include/XR/XRSpace.h
  30. 129 0
      Gems/XR/Code/Include/XR/XRSwapChain.h
  31. 96 0
      Gems/XR/Code/Include/XR/XRSystem.h
  32. 41 0
      Gems/XR/Code/Include/XR/XRSystemComponent.h
  33. 17 0
      Gems/XR/Code/Include/XR/XRUtils.h
  34. 9 0
      Gems/XR/Code/Source/Platform/Android/PAL_android.cmake
  35. 9 0
      Gems/XR/Code/Source/Platform/Android/XR_Traits_Android.h
  36. 10 0
      Gems/XR/Code/Source/Platform/Android/XR_Traits_Platform.h
  37. 12 0
      Gems/XR/Code/Source/Platform/Android/platform_private_android_files.cmake
  38. 8 0
      Gems/XR/Code/Source/Platform/Android/platform_private_static_android.cmake
  39. 9 0
      Gems/XR/Code/Source/Platform/Common/Unimplemented/Empty_Unimplemented.cpp
  40. 31 0
      Gems/XR/Code/Source/Platform/Common/Unimplemented/ModuleStub_Unimplemented.cpp
  41. 9 0
      Gems/XR/Code/Source/Platform/Linux/PAL_linux.cmake
  42. 9 0
      Gems/XR/Code/Source/Platform/Linux/XR_Traits_Linux.h
  43. 10 0
      Gems/XR/Code/Source/Platform/Linux/XR_Traits_Platform.h
  44. 12 0
      Gems/XR/Code/Source/Platform/Linux/platform_private_linux_files.cmake
  45. 8 0
      Gems/XR/Code/Source/Platform/Linux/platform_private_static_linux.cmake
  46. 9 0
      Gems/XR/Code/Source/Platform/Mac/PAL_mac.cmake
  47. 10 0
      Gems/XR/Code/Source/Platform/Windows/PAL_windows.cmake
  48. 10 0
      Gems/XR/Code/Source/Platform/Windows/XR_Traits_Platform.h
  49. 9 0
      Gems/XR/Code/Source/Platform/Windows/XR_Traits_Windows.h
  50. 8 0
      Gems/XR/Code/Source/Platform/Windows/platform_private_static_windows.cmake
  51. 12 0
      Gems/XR/Code/Source/Platform/Windows/platform_private_windows_files.cmake
  52. 9 0
      Gems/XR/Code/Source/Platform/iOS/PAL_ios.cmake
  53. 60 0
      Gems/XR/Code/Source/XRDevice.cpp
  54. 40 0
      Gems/XR/Code/Source/XRFactory.cpp
  55. 29 0
      Gems/XR/Code/Source/XRInput.cpp
  56. 23 0
      Gems/XR/Code/Source/XRInstance.cpp
  57. 41 0
      Gems/XR/Code/Source/XRModule.cpp
  58. 61 0
      Gems/XR/Code/Source/XRSession.cpp
  59. 28 0
      Gems/XR/Code/Source/XRSpace.cpp
  60. 44 0
      Gems/XR/Code/Source/XRSwapChain.cpp
  61. 229 0
      Gems/XR/Code/Source/XRSystem.cpp
  62. 90 0
      Gems/XR/Code/Source/XRSystemComponent.cpp
  63. 47 0
      Gems/XR/Code/Source/XRUtils.cpp
  64. 32 0
      Gems/XR/Code/xr_private_common_files.cmake
  65. 11 0
      Gems/XR/Code/xr_private_common_shared_files.cmake
  66. 11 0
      Gems/XR/Code/xr_stub_module.cmake
  67. 19 0
      Gems/XR/gem.json
  68. 二進制
      Gems/XR/preview.png

+ 11 - 0
Gems/XR/3rdParty/Platform/Android/BuiltInPackages_android.cmake

@@ -0,0 +1,11 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#
+

+ 11 - 0
Gems/XR/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake

@@ -0,0 +1,11 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#
+

+ 10 - 0
Gems/XR/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake

@@ -0,0 +1,10 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#

+ 10 - 0
Gems/XR/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake

@@ -0,0 +1,10 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#

+ 10 - 0
Gems/XR/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake

@@ -0,0 +1,10 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#

+ 17 - 0
Gems/XR/CMakeLists.txt

@@ -0,0 +1,17 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(gem_path ${CMAKE_CURRENT_LIST_DIR})
+set(gem_json ${gem_path}/gem.json)
+o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path)
+
+o3de_pal_dir(pal_3rdparty_dir ${CMAKE_CURRENT_LIST_DIR}/3rdParty/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}")
+
+include(${pal_3rdparty_dir}/BuiltInPackages_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
+
+add_subdirectory(Code)

+ 77 - 0
Gems/XR/Code/CMakeLists.txt

@@ -0,0 +1,77 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+o3de_pal_dir(pal_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/XR/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}")
+o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}")
+
+include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
+
+if(PAL_TRAIT_XR_TARGETS_ALREADY_DEFINED)
+    return() # XR targets already defined in PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
+endif()
+
+if(NOT PAL_TRAIT_XR_SUPPORTED)
+
+    # Create stub modules. Once we support gem loading configuration, we can remove this stubbed targets
+    ly_add_target(
+        NAME XR ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
+        NAMESPACE Gem
+        FILES_CMAKE
+            xr_stub_module.cmake
+        INCLUDE_DIRECTORIES
+            PRIVATE
+                Source
+        BUILD_DEPENDENCIES
+            PRIVATE
+                AZ::AzCore
+    )
+
+    return() # Do not create the rest of the targets
+
+endif()
+
+ly_add_target(
+    NAME XR.Static STATIC
+    NAMESPACE Gem
+    FILES_CMAKE
+        xr_private_common_files.cmake
+        ${pal_source_dir}/platform_private_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
+        ${pal_include_dir}/platform_private_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
+    PLATFORM_INCLUDE_FILES
+        ${pal_source_dir}/platform_private_static_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
+    INCLUDE_DIRECTORIES
+        PRIVATE
+            Source
+            ${pal_source_dir}
+        PUBLIC
+            Include
+            ${pal_include_dir}
+    BUILD_DEPENDENCIES
+        PUBLIC
+            AZ::AzCore
+            AZ::AzFramework
+            AZ::AtomCore
+            Gem::Atom_RPI.Public
+)
+
+ly_add_target(
+    NAME XR ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
+    NAMESPACE Gem
+    FILES_CMAKE
+        xr_private_common_shared_files.cmake
+    INCLUDE_DIRECTORIES
+        PRIVATE
+            Source
+            ${pal_source_dir}
+        PUBLIC
+            Include
+    BUILD_DEPENDENCIES
+        PRIVATE
+            Gem::XR.Static
+)
+

+ 13 - 0
Gems/XR/Code/Include/XR/Platform/Android/XR_Android.h

@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <AzCore/base.h>
+#include <AzCore/PlatformIncl.h>
+#include <AzCore/std/algorithm.h>
+

+ 9 - 0
Gems/XR/Code/Include/XR/Platform/Android/XR_Platform.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <XR_Android.h>

+ 12 - 0
Gems/XR/Code/Include/XR/Platform/Android/platform_private_android_files.cmake

@@ -0,0 +1,12 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    XR_Platform.h
+    XR_Android.h
+)

+ 14 - 0
Gems/XR/Code/Include/XR/Platform/Linux/XR_Linux.h

@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <AzCore/base.h>
+#include <AzCore/PlatformIncl.h>
+#include <AzCore/std/algorithm.h>
+
+

+ 10 - 0
Gems/XR/Code/Include/XR/Platform/Linux/XR_Platform.h

@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <XR_Linux.h>

+ 11 - 0
Gems/XR/Code/Include/XR/Platform/Linux/platform_private_linux_files.cmake

@@ -0,0 +1,11 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    XR_Platform.h
+)

+ 13 - 0
Gems/XR/Code/Include/XR/Platform/Mac/XR_Mac.h

@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <AzCore/base.h>
+#include <AzCore/PlatformIncl.h>
+#include <AzCore/std/algorithm.h>
+

+ 9 - 0
Gems/XR/Code/Include/XR/Platform/Mac/XR_Platform.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+

+ 10 - 0
Gems/XR/Code/Include/XR/Platform/Mac/platform_private_mac_files.cmake

@@ -0,0 +1,10 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+)

+ 9 - 0
Gems/XR/Code/Include/XR/Platform/Windows/XR_Platform.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <XR_Windows.h>

+ 12 - 0
Gems/XR/Code/Include/XR/Platform/Windows/XR_Windows.h

@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <AzCore/base.h>
+#include <AzCore/PlatformIncl.h>
+#include <AzCore/std/algorithm.h>

+ 12 - 0
Gems/XR/Code/Include/XR/Platform/Windows/platform_private_windows_files.cmake

@@ -0,0 +1,12 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    XR_Platform.h
+    XR_Windows.h
+)

+ 10 - 0
Gems/XR/Code/Include/XR/Platform/iOS/XR_Platform.h

@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+

+ 10 - 0
Gems/XR/Code/Include/XR/Platform/iOS/platform_private_ios_files.cmake

@@ -0,0 +1,10 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+)

+ 38 - 0
Gems/XR/Code/Include/XR/XRBase.h

@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+
+#include <AzCore/std/smart_ptr/intrusive_ptr.h>
+#include <AzCore/std/string/string.h>
+#include <AzCore/std/containers/vector.h>
+
+namespace XR
+{
+    template <typename T>
+    using Ptr = AZStd::intrusive_ptr<T>;
+
+    template<typename T>
+    using ConstPtr = AZStd::intrusive_ptr<const T>;
+
+    using StringList = AZStd::vector<AZStd::string>;
+    using RawStringList = AZStd::vector<const char*>;
+    
+    enum class  Side : uint32_t
+    {
+        Left = 0,
+        Right,
+        Count
+    }; 
+
+#define RETURN_RESULTCODE_IF_UNSUCCESSFUL(result) \
+    if (result != AZ::RHI::ResultCode::Success) {\
+        return result;\
+    }
+}
+

+ 100 - 0
Gems/XR/Code/Include/XR/XRDevice.h

@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <Atom/RHI/XRRenderingInterface.h>
+#include <Atom/RPI.Public/XR/XRRenderingInterface.h>
+#include <XR/XRBase.h>
+#include <XR/XRInstance.h>
+#include <XR/XRSwapChain.h>
+#include <XR/XRObject.h>
+
+namespace XR
+{
+    //! Base XR device class which will provide access to the back-end concrete object
+    class Session;
+    class Device
+        : public XR::Object
+    {
+    public:
+        AZ_CLASS_ALLOCATOR(Device, AZ::SystemAllocator, 0);
+        AZ_RTTI(Device, "{A31B0DC2-BD54-443E-9350-EB1B10670FF9}");
+
+        Device() = default;
+        virtual ~Device() = default;
+
+        struct Descriptor
+        {
+            AZ::RHI::ValidationMode m_validationMode = AZ::RHI::ValidationMode::Disabled;
+            Ptr<Instance> m_instance;
+        };
+
+        //! Create the xr specific native device object and populate the XRDeviceDescriptor with it.
+        virtual AZ::RHI::ResultCode InitDeviceInternal(AZ::RHI::XRDeviceDescriptor* instanceDescriptor) = 0;
+        
+        //! Returns true if rendering data is valid for the current frame.
+        virtual bool ShouldRender() const = 0;
+        
+        //! Returns fov data for a give view index.
+        virtual AZ::RPI::FovData GetViewFov(AZ::u32 viewIndex) const = 0;
+
+        //! Returns pose data for a give view index.
+        virtual AZ::RPI::PoseData GetViewPose(AZ::u32 viewIndex) const = 0;
+
+        //! Init the XR device.
+        AZ::RHI::ResultCode Init(Descriptor descriptor);
+        
+        //! Signal Begin frame to the underlying back end.
+        bool BeginFrame();
+
+        //! Signal End frame to the underlying back end.
+        void EndFrame(Ptr<SwapChain>);
+
+        //! Signal the back-end to acquire swapchain images.
+        bool AcquireSwapChainImage(AZ::u32 viewIndex, SwapChain* swapChain);
+
+        //! Register XR session with the device.
+        void RegisterSession(Ptr<Session> session);
+    
+        //! UnRegister XR session with the device.
+        void UnRegisterSession();
+
+        //! Get the descriptor.
+        const Descriptor& GetDescriptor() const;
+
+        //! Get the xr session registered with the device
+        Ptr<Session> GetSession() const;
+
+    protected:
+    
+        //! Called when the device is being shutdown.
+        virtual void ShutdownInternal() = 0;
+
+        //! Called when the device is beginning a frame for processing.
+        virtual bool BeginFrameInternal() = 0;
+
+        //! Called when the device is ending a frame for processing. 
+        //! Pass in the active swapchain in order to allow the back end to release the swap chain images
+        virtual void EndFrameInternal(XR::Ptr<XR::SwapChain>) = 0;
+
+        //! Called when the device is beginning a frame for processing.
+        virtual bool AcquireSwapChainImageInternal(AZ::u32 viewIndex, XR::SwapChain* baseSwapChain) = 0;
+
+    private:
+
+        ///////////////////////////////////////////////////////////////////
+        // XR::Object
+        void Shutdown() override;
+        ///////////////////////////////////////////////////////////////////
+
+        Ptr<Session> m_session;
+        Descriptor m_descriptor;
+    };
+}

+ 77 - 0
Gems/XR/Code/Include/XR/XRFactory.h

@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/std/containers/vector.h>
+
+#include <XR/XRBase.h>
+#include <XR/XRInstance.h>
+#include <XR/XRDevice.h>
+#include <XR/XRSession.h>
+#include <XR/XRInput.h>
+#include <XR/XRSpace.h>
+#include <XR/XRSwapChain.h>
+
+namespace XR
+{
+    //! Interface responsible for creating all the XR objects which are
+    //! internally backed by concrete objects
+    class Factory
+    {
+    public:
+        AZ_CLASS_ALLOCATOR(Factory, AZ::SystemAllocator, 0);
+        AZ_RTTI(Factory, "{A3D7271A-64FD-442C-9116-DBC32224222F}");
+
+        Factory() = default;
+        virtual ~Factory() = default;
+
+        AZ_DISABLE_COPY_MOVE(Factory);
+
+        //! Returns the component service name CRC used by the platform RHI system component.
+        static AZ::u32 GetPlatformService();
+
+        //! Registers the global factory instance.
+        static void Register(XR::Factory* instance);
+
+        //! Unregisters the global factory instance.
+        static void Unregister(XR::Factory* instance);
+
+        //! Returns if the factory ready.
+        static bool IsReady();
+
+        //! Access the global factory instance.
+        static XR::Factory& Get();
+
+        //! Create XR::Instance object.
+        virtual Ptr<XR::Instance> CreateInstance() = 0;
+
+        //! Create XR::Device object.
+        virtual Ptr<XR::Device> CreateDevice() = 0;
+
+        //! Create XR::Session object.
+        virtual Ptr<XR::Session> CreateSession() = 0;
+
+        //! Create XR::Input object.
+        virtual Ptr<XR::Input> CreateInput() = 0;
+
+        //! Create XR::Space object.
+        virtual Ptr<XR::Space> CreateSpace() = 0;
+
+        //! Create XR::Swapchain object.
+        virtual Ptr<XR::SwapChain> CreateSwapChain() = 0;
+
+        //! Create XR::Swapchain::View object.
+        virtual Ptr<XR::SwapChain::View> CreateSwapChainView() = 0;
+
+        //! Create XR::Swapchain::Image object.
+        virtual Ptr<XR::SwapChain::Image> CreateSwapChainImage() = 0;
+    };
+} // namespace XR
+

+ 55 - 0
Gems/XR/Code/Include/XR/XRInput.h

@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <XR/XRBase.h>
+#include <XR/XRObject.h>
+
+namespace XR
+{ 
+    class Session;
+    class Instance;
+    // This class will be responsible for creating XR::Input
+    // which manage event queue or poll actions
+    class Input
+        : public XR::Object
+    {
+    public:
+        AZ_CLASS_ALLOCATOR(Input, AZ::SystemAllocator, 0);
+        AZ_RTTI(Input, "{DCDFC6A7-B457-414B-BC24-0831C2AC628B}");
+
+        Input() = default;
+        virtual ~Input() = default;
+        
+        struct Descriptor
+        {
+            Ptr<Instance> m_instance;
+            Ptr<Device> m_device;
+            Ptr<Session> m_session;
+        };
+        
+        AZ::RHI::ResultCode Init(Descriptor descriptor);
+        const Descriptor& GetDescriptor() const;
+
+        virtual void PollActions() = 0;
+       
+    private:
+        ///////////////////////////////////////////////////////////////////
+        // XR::Object
+        void Shutdown() override;
+        ///////////////////////////////////////////////////////////////////
+
+        //! Called when the XR instance is being shutdown.
+        virtual void ShutdownInternal() = 0;
+        virtual AZ::RHI::ResultCode InitInternal() = 0;
+
+        Descriptor m_descriptor;
+    };
+} // namespace XR

+ 59 - 0
Gems/XR/Code/Include/XR/XRInstance.h

@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <Atom/RHI/ValidationLayer.h>
+#include <Atom/RHI/XRRenderingInterface.h>
+#include <XR/XRBase.h>
+#include <XR/XRObject.h>
+
+namespace XR
+{
+    class Instance
+        : public XR::Object
+    {
+    public:
+        AZ_CLASS_ALLOCATOR(Instance, AZ::SystemAllocator, 0);
+        AZ_RTTI(Instance, "{1C457924-56A4-444F-BC72-4D31A097BA70}");
+
+        Instance() = default;
+        virtual ~Instance() = default;
+
+        //! Init the back-end instance. It is responsible for figuring out supported layers and extensions 
+        //! and based on that a xr instance is created. It also has logging support based on validation mode.  
+        AZ::RHI::ResultCode Init(AZ::RHI::ValidationMode validationMode);
+
+        //! API to init the native instance object and populate the XRInstanceDecriptor with it.
+        virtual AZ::RHI::ResultCode InitNativeInstance(AZ::RHI::XRInstanceDescriptor* instanceDescriptor) = 0;
+
+        //! Get number of physical devices for XR.
+        virtual AZ::u32 GetNumPhysicalDevices() const = 0;
+
+        //! API to retrieve the native physical device for a specific index.
+        virtual AZ::RHI::ResultCode GetXRPhysicalDevice(AZ::RHI::XRPhysicalDeviceDescriptor* physicalDeviceDescriptor, int32_t index) = 0;
+
+    private:
+
+        ///////////////////////////////////////////////////////////////////
+        // XR::Object
+        void Shutdown() override;
+        ///////////////////////////////////////////////////////////////////
+
+        //! Called when the XR instance is being shutdown.
+        virtual void ShutdownInternal() = 0;
+
+        //! API to allow backend object to initialize native xr instance. 
+        virtual AZ::RHI::ResultCode InitInstanceInternal(AZ::RHI::ValidationMode m_validationMode) = 0;
+       
+        //Cache validation mode in case the backend object needs to use it.
+        AZ::RHI::ValidationMode m_validationMode = AZ::RHI::ValidationMode::Disabled;
+    };
+
+} // namespace XR

+ 77 - 0
Gems/XR/Code/Include/XR/XRObject.h

@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <AzCore/std/smart_ptr/intrusive_base.h>
+#include <AzCore/Name/Name.h>
+
+namespace XR
+{
+    //! All objects have an explicit Init / Shutdown path in addition to
+    //! creation / deletion. The user is expected to Init the derived variant
+    //! in order to use it. This extension allows the user to forgo shutdown
+    //! explicitly and depend on the Ptr ref-counting if necessary.
+    //! This requires that Shutdown properly account for being called multiple times.
+    struct ObjectDeleter
+        : public AZStd::intrusive_default_delete
+    {
+        template <typename U>
+        void operator () (U* p) const;
+    };
+
+    //! Base class for any persistent resource. Provides a name, reference
+    //! counting, and a common RTTI base class for all objects .
+    class Object
+        : public AZStd::intrusive_refcount<AZStd::atomic_uint, ObjectDeleter>
+    {
+    public:
+        AZ_RTTI(Object, "{74FCA8BF-CBDA-43EB-A378-89F752ED2FCA}");
+        virtual ~Object() = default;
+
+        //! Sets the name of the object.
+        void SetName(const AZ::Name& name)
+        {
+            m_name = name;
+            SetNameInternal(m_name.GetStringView());
+        }
+
+        //! Returns the name set on the object by SetName
+        const AZ::Name& GetName() const { return m_name; }
+
+    protected:
+        Object() = default;
+
+    private:
+        // Friended to allow private call to Shutdown.
+        friend struct ObjectDeleter;
+
+        //! Shuts down the object. Derived classes can make this public if it fits
+        //! with their lifecycle model (i.e. if they use an explicit Init / Shutdown).
+        //! By default, it is private in order to maintain consistency with a simpler RAII lifecycle.
+        virtual void Shutdown() {};
+
+        virtual void SetNameInternal([[maybe_unused]] const AZStd::string_view& name) {}
+
+        //! Object name. Very helpful for debugging
+        AZ::Name m_name;
+    };
+
+    template <typename U>
+    void ObjectDeleter::operator () (U* p) const
+    {
+        //! Recover the mutable parent object pointer from the refcount base class.
+        Object* object = const_cast<Object*>(static_cast<const Object*>(p));
+
+        //! Shuts down the object before deletion.
+        object->Shutdown();
+
+        //! Then invoke the base delete policy.
+        AZStd::intrusive_default_delete::operator () (object);
+    }
+}
+

+ 98 - 0
Gems/XR/Code/Include/XR/XRSession.h

@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Memory/SystemAllocator.h>
+
+#include <XR/XRBase.h>
+#include <XR/XRInput.h>
+#include <XR/XRObject.h>
+#include <XR/XRSpace.h>
+
+namespace XR
+{
+    class Device;
+
+    // This class will be responsible for creating XR::Session and
+    // all the code around managing the session state
+    class Session
+        : public XR::Object
+    {
+    public:
+        AZ_CLASS_ALLOCATOR(Session, AZ::SystemAllocator, 0);
+        AZ_RTTI(Session, "{E7276FE1-94B8-423A-9C1D-1BCF1A0066BC}");
+
+        struct Descriptor
+        {
+            AZ::RHI::ValidationMode m_validationMode = AZ::RHI::ValidationMode::Disabled;
+            Ptr<Device> m_device;
+            Ptr<Instance> m_instance;
+        };
+
+        Session() = default;
+        virtual ~Session() = default;
+        
+        //! Initialize the XrSession object which is responsible for creating
+        //! XrInput and XrSpace
+        AZ::RHI::ResultCode Init(const Descriptor& descriptor);
+
+        //! Get the descriptor for the class
+        const Descriptor& GetDescriptor() const;
+
+        //! Get the Xr Input object
+        Input* GetInput() const;
+
+        //! Get the Xr Space object
+        Space* GetSpace() const;
+        
+        //! Return true if session is running
+        virtual bool IsSessionRunning() const = 0;
+
+        //! Return true if session is focused
+        virtual bool IsSessionFocused() const = 0;
+
+        //! Return true if a restart is requested
+        virtual bool IsRestartRequested() const = 0;
+    
+        //! Return true if render loop skip is requested
+        virtual bool IsExitRenderLoopRequested() const = 0;
+
+        //! Poll events and process the pending messages accordingly
+        virtual void PollEvents() = 0;
+
+        //! All the back end object to initialize properly
+        virtual AZ::RHI::ResultCode InitInternal(AZ::RHI::XRSessionDescriptor* descriptor) = 0;
+
+        //! Allow the back-end to cache the controller space data
+        virtual void LocateControllerSpace(AZ::u32 handIndex) = 0;
+
+        //! Api to retrieve the controller space data
+        virtual AZ::RPI::PoseData GetControllerPose(AZ::u32 handIndex) const = 0;
+
+        //! Api to retrieve the controller scale data
+        virtual float GetControllerScale(AZ::u32 handIndex) const = 0;
+
+        //! Api to retrieve the front view space data
+        virtual AZ::RPI::PoseData GetViewFrontPose() const = 0;
+
+    private:
+
+        ///////////////////////////////////////////////////////////////////
+        // XR::Object
+        void Shutdown() override;
+        ///////////////////////////////////////////////////////////////////
+
+        //! Called when the XR instance is being shutdown.
+        virtual void ShutdownInternal() = 0;
+
+        Ptr<Input> m_input;
+        Ptr<Space> m_space;
+        Descriptor m_descriptor;
+    };
+} // namespace XR

+ 46 - 0
Gems/XR/Code/Include/XR/XRSpace.h

@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/std/smart_ptr/intrusive_base.h>
+#include <XR/XRObject.h>
+
+namespace XR
+{
+    //! Base XR Space class which will provide access to the back-end concrete object
+    class Space
+        : public ::XR::Object
+    {
+	    
+    public:
+        AZ_CLASS_ALLOCATOR(Space, AZ::SystemAllocator, 0);
+        AZ_RTTI(Space, "{A78A37F1-8861-4EB4-8FC6-0E9C11394EF1}");
+
+        struct Descriptor
+        {
+            AZ::RHI::ValidationMode m_validationMode = AZ::RHI::ValidationMode::Disabled;
+        };
+
+        AZ::RHI::ResultCode Init(Descriptor descriptor);
+        const Space::Descriptor& GetDescriptor() const;
+    private:
+
+        ///////////////////////////////////////////////////////////////////
+        // XR::Object
+        void Shutdown() override;
+        ///////////////////////////////////////////////////////////////////
+
+        //! Called when the XR instance is being shutdown.
+        virtual void ShutdownInternal() = 0;
+        virtual AZ::RHI::ResultCode InitInternal() = 0;
+       
+        Descriptor m_descriptor;
+    };
+} // namespace XR

+ 129 - 0
Gems/XR/Code/Include/XR/XRSwapChain.h

@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/std/containers/vector.h>
+#include <AzCore/std/smart_ptr/intrusive_ptr.h>
+#include <Atom/RHI/XRRenderingInterface.h>
+#include <XR/XRObject.h>
+
+namespace XR
+{
+    class Session;
+    class Device;
+
+    //! This class will be responsible for creating multiple XR::SwapChain::ViewSwapchains
+    //! (one per view). Each XR::SwapChain::ViewSwapchain will then be responsible
+    //! for manging and synchronizing multiple swap chain images
+    class SwapChain 
+        : public XR::Object
+    {
+    public:
+        AZ_CLASS_ALLOCATOR(SwapChain, AZ::SystemAllocator, 0);
+        AZ_RTTI(SwapChain, "{0C666E76-E4B7-4097-8D14-713DC2C446EF}");
+
+        class Image 
+            : public AZStd::intrusive_base
+        {
+        public:
+            AZ_CLASS_ALLOCATOR(Image, AZ::SystemAllocator, 0);
+            AZ_RTTI(Image, "{4037835D-F1BB-4407-BC98-2299CC7BE0A3}");
+
+            Image() = default;
+            virtual ~Image() = default;
+        };
+
+        class View 
+            : public AZStd::intrusive_base
+        {
+        public:
+            AZ_CLASS_ALLOCATOR(View, AZ::SystemAllocator, 0);
+            AZ_RTTI(View, "{774EB724-8261-4684-AA78-EDF6BBECD48A}");
+
+            View() = default;
+            virtual ~View() = default;
+
+            virtual void Shutdown() = 0;
+            virtual AZ::u32 GetCurrentImageIndex() const = 0;
+            //! All the images associated with this View
+            AZStd::vector<Ptr<SwapChain::Image>> m_images;
+
+            //! The active image index
+            AZ::u32 m_activeImageIndex = 0;
+
+            //! Number of swapchain images associated with this view.
+            AZ::u32 m_numImages = 0;
+
+            //! Returns if an image acquired for this view.
+            bool m_isImageAcquired = false;
+
+            //! Width of the swap chain view.
+            AZ::u32 m_width = 0;
+    
+            //! Height of the swap chain view.
+            AZ::u32 m_height = 0;
+        };
+
+        struct Descriptor
+        {
+            AZ::RHI::ValidationMode m_validationMode = AZ::RHI::ValidationMode::Disabled;
+            Ptr<Instance> m_instance;
+            Ptr<Session> m_session;
+            Ptr<Device> m_device;
+        };
+
+        //! Returns the view swap chain related to the index.
+        SwapChain::View* GetView(const AZ::u32 swapChainIndex) const;
+
+        //! Returns the image associated with the provided image
+        //! index and view swap chain index.
+        SwapChain::Image* GetImage(AZ::u32 imageIndex, AZ::u32 swapChainIndex) const;
+
+        //! Initialize the XR swapchain.
+        AZ::RHI::ResultCode Init(const Descriptor& descriptor);
+
+        //! Get the descriptor. 
+        const Descriptor& GetDescriptor() const;
+
+        //! Get the number of Xr views
+        AZ::u32 GetNumViews() const;
+
+        //! Api to allow the back end object to return the requested native swapchain image
+        virtual AZ::RHI::ResultCode GetSwapChainImage(AZ::RHI::XRSwapChainDescriptor* swapchainDescriptor) const = 0;
+       
+        //! Api to allow the back end to report the recommended swapchain width
+        virtual AZ::u32 GetSwapChainWidth(AZ::u32 viewIndex) const = 0;
+        
+        //! Api to allow the back end to report the recommended swapchain height
+        virtual AZ::u32 GetSwapChainHeight(AZ::u32 viewIndex) const = 0;
+
+    protected:
+        
+        //! Number of Xr views
+        AZ::u32 m_numViews = 0;
+
+        //! Vector to hold all the SwapChain View objects
+        AZStd::vector<Ptr<SwapChain::View>> m_viewSwapchains;
+   
+    private:
+        ///////////////////////////////////////////////////////////////////
+        // XR::Object override
+        void Shutdown() override;
+        ///////////////////////////////////////////////////////////////////
+
+        //! Called when the swapchain is being shutdown.
+        virtual void ShutdownInternal() = 0;
+
+        //! Api to allow the back end object to initialize  
+        virtual AZ::RHI::ResultCode InitInternal() = 0;
+
+        Descriptor m_descriptor;
+    };
+} // namespace XR

+ 96 - 0
Gems/XR/Code/Include/XR/XRSystem.h

@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/base.h>
+#include <AzCore/Component/TickBus.h>
+#include <AzCore/Memory/SystemAllocator.h>
+#include <Atom/RHI/XRRenderingInterface.h>
+#include <Atom/RHI/ValidationLayer.h>
+#include <Atom/RPI.Public/XR/XRRenderingInterface.h>
+#include <XR/XRInstance.h>
+#include <XR/XRDevice.h>
+#include <XR/XRSession.h>
+#include <XR/XRSwapChain.h>
+
+namespace XR
+{
+    //! This class is the window to everything XR related. It implements 
+    //! RPI::RenderingInterface and RHI::RenderingInterface but
+    //! can be extended to implement other non rendering interfaces if needed. 
+    class System
+        : public AZ::RPI::XRRenderingInterface
+        , public AZ::RHI::XRRenderingInterface
+        , public AZ::SystemTickBus::Handler
+        , public AZStd::intrusive_base
+    {
+    public:
+        AZ_CLASS_ALLOCATOR(System, AZ::SystemAllocator, 0);
+        AZ_RTTI(System, "{C3E0291D-FB30-4E27-AB0D-14606A8C3C1F}");
+
+        AZ_DISABLE_COPY_MOVE(System);
+
+        System() = default;
+        ~System() = default;
+
+        struct Descriptor
+        {
+            AZ::RHI::ValidationMode m_validationMode = AZ::RHI::ValidationMode::Disabled;
+        };
+
+        //! Init the XRSystem.
+        void Init(const Descriptor& descriptor);
+
+        //! Destroy any relevant objects held by this .class 
+        void Shutdown();
+
+        //! Handle XR events and actions
+        void OnSystemTick() override;
+
+        ///////////////////////////////////////////////////////////////////
+        // AZ::RPI::XRRenderingInterface overrides
+        AZ::RHI::ResultCode InitInstance() override;
+        void AcquireSwapChainImage(AZ::u32 viewIndex) override;
+        AZ::u32 GetNumViews() const override;
+        AZ::RHI::ResultCode GetSwapChainImage(AZ::RHI::XRSwapChainDescriptor* swapchainDescriptor) const override;
+        AZ::u32 GetSwapChainWidth(AZ::u32 viewIndex) const override;
+        AZ::u32 GetSwapChainHeight(AZ::u32 viewIndex) const override;
+        AZ::RPI::FovData GetViewFov(AZ::u32 viewIndex) const override;
+        AZ::RPI::PoseData GetViewPose(AZ::u32 viewIndex) const override;
+        AZ::RPI::PoseData GetViewFrontPose() const override;
+        AZ::RPI::PoseData GetControllerPose(AZ::u32 handIndex) const override;
+        float GetControllerScale(AZ::u32 handIndex) const override;
+        bool ShouldRender() const override;
+        AZ::Matrix4x4 CreateProjectionOffset(float angleLeft, float angleRight, 
+                                             float angleBottom, float angleTop, 
+                                             float nearDist, float farDist) override;
+        ///////////////////////////////////////////////////////////////////
+
+        ///////////////////////////////////////////////////////////////////
+        // AZ::RHI::XRRenderingInterface overrides
+        AZ::RHI::ResultCode InitNativeInstance(AZ::RHI::XRInstanceDescriptor* instanceDescriptor) override;
+        AZ::u32 GetNumPhysicalDevices() const override;
+        AZ::RHI::ResultCode GetXRPhysicalDevice(AZ::RHI::XRPhysicalDeviceDescriptor* physicalDeviceDescriptor, int32_t index) override;
+        AZ::RHI::ResultCode CreateDevice(AZ::RHI::XRDeviceDescriptor* deviceDescriptor) override;
+        AZ::RHI::ResultCode CreateSession(AZ::RHI::XRSessionDescriptor* sessionDescriptor) override;
+        AZ::RHI::ResultCode CreateSwapChain() override;
+        AZ::u32 GetCurrentImageIndex(AZ::u32 viewIndex) const override;
+        void BeginFrame() override;
+        void EndFrame() override;
+        ///////////////////////////////////////////////////////////////////
+
+    private:
+        Ptr<Instance> m_instance;
+        Ptr<Session> m_session;
+        Ptr<SwapChain> m_swapChain;
+        Ptr<Device> m_device;
+        AZ::RHI::ValidationMode m_validationMode = AZ::RHI::ValidationMode::Disabled;
+        bool m_isInFrame = false;
+    };
+} // namespace XR

+ 41 - 0
Gems/XR/Code/Include/XR/XRSystemComponent.h

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <XR/XRSystem.h>
+#include <AzCore/Component/Component.h>
+
+namespace XR
+{
+    //! This class is the component related to the common XR module.
+    class SystemComponent final
+        : public AZ::Component
+    {
+    public:
+        AZ_COMPONENT(SystemComponent, "{93A3A7E7-5188-49CD-8C37-26816476A3AE}");
+
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void Reflect(AZ::ReflectContext* context);
+
+        SystemComponent();
+        ~SystemComponent() = default;
+
+        //////////////////////////////////////////////////////////////////////////
+        // Component
+        void Activate() override;
+        void Deactivate() override;
+        //////////////////////////////////////////////////////////////////////////
+
+    private:
+        //! Check is OpenXR is enable via command line option or settings registry.
+        bool IsOpenXREnabled();
+
+        Ptr<XR::System> m_xrSystem;
+    };
+}

+ 17 - 0
Gems/XR/Code/Include/XR/XRUtils.h

@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Math/Matrix4x4.h>
+
+namespace XR
+{
+    //! Creates an off-center projection matrix suitable for VR
+    AZ::Matrix4x4 CreateProjectionOffset(float angleLeft, float angleRight, float angleBottom, float angleTop, float nearDist, float farDist);
+}

+ 9 - 0
Gems/XR/Code/Source/Platform/Android/PAL_android.cmake

@@ -0,0 +1,9 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(PAL_TRAIT_XR_SUPPORTED TRUE)

+ 9 - 0
Gems/XR/Code/Source/Platform/Android/XR_Traits_Android.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+

+ 10 - 0
Gems/XR/Code/Source/Platform/Android/XR_Traits_Platform.h

@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <OpenXRVk_Traits_Android.h>

+ 12 - 0
Gems/XR/Code/Source/Platform/Android/platform_private_android_files.cmake

@@ -0,0 +1,12 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    XR_Traits_Android.h
+    XR_Traits_Platform.h
+)

+ 8 - 0
Gems/XR/Code/Source/Platform/Android/platform_private_static_android.cmake

@@ -0,0 +1,8 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+

+ 9 - 0
Gems/XR/Code/Source/Platform/Common/Unimplemented/Empty_Unimplemented.cpp

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+// This is an intentionally empty file used to compile on platforms that cannot support artifacts without at least one source file

+ 31 - 0
Gems/XR/Code/Source/Platform/Common/Unimplemented/ModuleStub_Unimplemented.cpp

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#include <AzCore/Module/Module.h>
+
+namespace AZ
+{
+    namespace XR
+    {
+        class Module
+            : public AZ::Module
+        {
+        public:
+            AZ_RTTI(Module, "{3A378AD3-B176-43F4-A49B-9D9FE053243A}", AZ::Module);
+
+            Module() = default;
+            ~Module() override = default;
+
+            AZ::ComponentTypeList GetRequiredSystemComponents() const override
+            {
+                return AZ::ComponentTypeList();
+            }
+        };
+    }
+}
+
+AZ_DECLARE_MODULE_CLASS(Gem_XR_Private, AZ::XR::Module)

+ 9 - 0
Gems/XR/Code/Source/Platform/Linux/PAL_linux.cmake

@@ -0,0 +1,9 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(PAL_TRAIT_XR_SUPPORTED TRUE)

+ 9 - 0
Gems/XR/Code/Source/Platform/Linux/XR_Traits_Linux.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+

+ 10 - 0
Gems/XR/Code/Source/Platform/Linux/XR_Traits_Platform.h

@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <XR_Traits_Linux.h>

+ 12 - 0
Gems/XR/Code/Source/Platform/Linux/platform_private_linux_files.cmake

@@ -0,0 +1,12 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    XR_Traits_Linux.h
+    XR_Traits_Platform.h
+)

+ 8 - 0
Gems/XR/Code/Source/Platform/Linux/platform_private_static_linux.cmake

@@ -0,0 +1,8 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+

+ 9 - 0
Gems/XR/Code/Source/Platform/Mac/PAL_mac.cmake

@@ -0,0 +1,9 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(PAL_TRAIT_XR_SUPPORTED FALSE)

+ 10 - 0
Gems/XR/Code/Source/Platform/Windows/PAL_windows.cmake

@@ -0,0 +1,10 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(PAL_TRAIT_XR_SUPPORTED TRUE)
+

+ 10 - 0
Gems/XR/Code/Source/Platform/Windows/XR_Traits_Platform.h

@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include <XR_Traits_Windows.h>

+ 9 - 0
Gems/XR/Code/Source/Platform/Windows/XR_Traits_Windows.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+

+ 8 - 0
Gems/XR/Code/Source/Platform/Windows/platform_private_static_windows.cmake

@@ -0,0 +1,8 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+

+ 12 - 0
Gems/XR/Code/Source/Platform/Windows/platform_private_windows_files.cmake

@@ -0,0 +1,12 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    XR_Traits_Windows.h
+    XR_Traits_Platform.h
+)

+ 9 - 0
Gems/XR/Code/Source/Platform/iOS/PAL_ios.cmake

@@ -0,0 +1,9 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(PAL_TRAIT_XR_SUPPORTED FALSE)

+ 60 - 0
Gems/XR/Code/Source/XRDevice.cpp

@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <XR/XRDevice.h>
+#include <XR/XRSwapChain.h>
+
+namespace XR
+{
+    AZ::RHI::ResultCode Device::Init(Descriptor descriptor)
+    {
+        m_descriptor = descriptor;
+        return AZ::RHI::ResultCode::Success;
+    }
+    
+    const Device::Descriptor& Device::GetDescriptor() const
+    {
+        return m_descriptor;
+    }
+
+    Ptr<Session> Device::GetSession() const
+    {
+        return m_session;
+    }
+
+    bool Device::BeginFrame()
+    {
+        return BeginFrameInternal();
+    }
+
+    void Device::EndFrame(Ptr<SwapChain> swapChain)
+    {
+        EndFrameInternal(swapChain);
+    }
+
+    bool Device::AcquireSwapChainImage(AZ::u32 viewIndex, XR::SwapChain* baseSwapChain)
+    {
+        return AcquireSwapChainImageInternal(viewIndex, baseSwapChain);
+    }
+
+    void Device::RegisterSession(Ptr<Session> session)
+    {
+        m_session = session;
+    }
+
+    void Device::UnRegisterSession()
+    {
+        m_session = nullptr;
+    }
+
+    void Device::Shutdown()
+    {
+        ShutdownInternal();
+    }
+
+} // namespace XR

+ 40 - 0
Gems/XR/Code/Source/XRFactory.cpp

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <AzCore/Interface/Interface.h>
+#include <XR/XRFactory.h>
+
+namespace XR
+{
+    AZ::u32 Factory::GetPlatformService()
+    {
+        return AZ_CRC_CE("XRPlatformService");
+    }
+
+    void Factory::Register(Factory* instance)
+    {
+        AZ::Interface<Factory>::Register(instance);
+    }
+
+    void Factory::Unregister(Factory* instance)
+    {
+        AZ::Interface<Factory>::Unregister(instance);
+    }
+
+    bool Factory::IsReady()
+    {
+        return AZ::Interface<Factory>::Get() != nullptr;
+    }
+
+    Factory& Factory::Get()
+    {
+        Factory* factory = AZ::Interface<Factory>::Get();
+        AZ_Assert(factory, "XR::Factory failed to create!!!");
+        return *factory;
+    }
+} // namespace XR

+ 29 - 0
Gems/XR/Code/Source/XRInput.cpp

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <XR/XRInput.h>
+
+namespace XR
+{
+    AZ::RHI::ResultCode Input::Init(Descriptor descriptor)
+    {
+        m_descriptor = descriptor;
+        return InitInternal();
+    }
+
+    const Input::Descriptor& Input::GetDescriptor() const
+    {
+        return m_descriptor;
+    }
+
+    void Input::Shutdown()
+    {
+        ShutdownInternal();
+    }
+
+} // namespace XR

+ 23 - 0
Gems/XR/Code/Source/XRInstance.cpp

@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <XR/XRInstance.h>
+
+namespace XR
+{
+    AZ::RHI::ResultCode Instance::Init(AZ::RHI::ValidationMode validationMode)
+    {
+        m_validationMode = validationMode;
+        return InitInstanceInternal(validationMode);
+    }
+
+    void Instance::Shutdown()
+    {
+        ShutdownInternal();
+    }
+} // namespace XR

+ 41 - 0
Gems/XR/Code/Source/XRModule.cpp

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/Module/Module.h>
+#include <XR/XRSystemComponent.h>
+
+namespace XR
+{
+    class Module : public AZ::Module
+    {
+    public:
+        AZ_RTTI(Module, "{71A99524-7D31-42D3-955E-3F4774F310AC}", AZ::Module);
+        AZ_CLASS_ALLOCATOR(Module, AZ::SystemAllocator, 0);
+
+        Module()
+            : AZ::Module()
+        {
+            m_descriptors.insert(
+                m_descriptors.end(),
+                {
+                    SystemComponent::CreateDescriptor(),
+                });
+        }
+
+        AZ::ComponentTypeList GetRequiredSystemComponents() const override
+        {
+            return { azrtti_typeid<XR::SystemComponent>() };
+        }
+    };
+}
+
+// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
+// The first parameter should be GemName_GemIdLower
+// The second should be the fully qualified name of the class above
+AZ_DECLARE_MODULE_CLASS(Gem_XR, XR::Module)

+ 61 - 0
Gems/XR/Code/Source/XRSession.cpp

@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <XR/XRSession.h>
+#include <XR/XRFactory.h>
+#include <XR/XRDevice.h>
+
+namespace XR
+{
+    AZ::RHI::ResultCode Session::Init(const Descriptor& descriptor)
+    {
+        AZ::RHI::ResultCode result = AZ::RHI::ResultCode::Fail;
+        m_descriptor = descriptor;
+
+        m_space = Factory::Get().CreateSpace();
+        AZ_Error("XR", m_space, "XR Space was not created");
+        if (m_space)
+        {
+            result = m_space->Init(Space::Descriptor{ m_descriptor.m_validationMode});
+            AZ_Error("XR", result == AZ::RHI::ResultCode::Success, "XR Space was not initialized");
+            RETURN_RESULTCODE_IF_UNSUCCESSFUL(result);
+        }
+        
+        m_input = Factory::Get().CreateInput();
+        AZ_Error("XR", m_input, "XR Input was not created");
+        if (m_input)
+        {
+            result = m_input->Init(Input::Descriptor{ m_descriptor.m_instance, m_descriptor.m_device, this });
+            AZ_Error("XR", result == AZ::RHI::ResultCode::Success, "XR Input was not initialized");
+            RETURN_RESULTCODE_IF_UNSUCCESSFUL(result);
+        }
+        m_descriptor.m_device->RegisterSession(this);
+        return AZ::RHI::ResultCode::Success;
+    }
+
+    const Session::Descriptor& Session::GetDescriptor() const
+    {
+        return m_descriptor;
+    }
+
+    void Session::Shutdown()
+    {
+        m_descriptor.m_device->UnRegisterSession();
+        ShutdownInternal();
+    }
+    
+    Input* Session::GetInput() const
+    {
+        return m_input.get();
+    }
+
+    Space* Session::GetSpace() const
+    {
+        return m_space.get();
+    } 
+} // namespace XR

+ 28 - 0
Gems/XR/Code/Source/XRSpace.cpp

@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <XR/XRSpace.h>
+
+namespace XR
+{
+    AZ::RHI::ResultCode Space::Init(Descriptor descriptor)
+    {
+        m_descriptor = descriptor;
+        return InitInternal();
+    }
+
+    const Space::Descriptor& Space::GetDescriptor() const
+    {
+        return m_descriptor;
+    }
+
+    void Space::Shutdown()
+    {
+        ShutdownInternal();
+    }
+} // namespace XR

+ 44 - 0
Gems/XR/Code/Source/XRSwapChain.cpp

@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <XR/XRSwapChain.h>
+
+namespace XR
+{ 
+    SwapChain::View* SwapChain::GetView(const AZ::u32 swapchainIndex) const
+    {
+        return m_viewSwapchains[swapchainIndex].get();
+    }
+
+    SwapChain::Image* SwapChain::GetImage(AZ::u32 imageIndex, AZ::u32 swapchainIndex) const
+    {
+        return GetView(swapchainIndex)->m_images[imageIndex].get();
+    }
+
+    AZ::RHI::ResultCode SwapChain::Init(const Descriptor& descriptor)
+    {
+        m_descriptor = descriptor;
+        return InitInternal();
+    }
+    
+    const SwapChain::Descriptor& SwapChain::GetDescriptor() const
+    {
+        return m_descriptor;
+    }
+
+    AZ::u32 SwapChain::GetNumViews() const
+    {
+        return m_numViews;
+    }
+
+    void SwapChain::Shutdown()
+    {
+        ShutdownInternal();
+        m_viewSwapchains.clear();
+    }
+} // namespace XR

+ 229 - 0
Gems/XR/Code/Source/XRSystem.cpp

@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <AZCore/Interface/Interface.h>
+#include <AzCore/Debug/Profiler.h>
+#include <XR/XRFactory.h>
+#include <XR/XRSystem.h>
+#include <XR/XRUtils.h>
+
+namespace XR
+{
+    void System::Init(const System::Descriptor& descriptor)
+    {
+        m_validationMode = descriptor.m_validationMode;
+        AZ::SystemTickBus::Handler::BusConnect();
+    }
+
+    AZ::RHI::ResultCode System::InitInstance()
+    {
+        m_instance = Factory::Get().CreateInstance();
+
+        if (m_instance)
+        {
+            return m_instance->Init(m_validationMode);
+        }
+        return AZ::RHI::ResultCode::Fail;
+    }
+
+    AZ::RHI::ResultCode System::InitNativeInstance(AZ::RHI::XRInstanceDescriptor* instanceDescriptor)
+    {
+        return m_instance->InitNativeInstance(instanceDescriptor);
+    }
+
+    AZ::u32 System::GetNumPhysicalDevices() const
+    {
+        return m_instance->GetNumPhysicalDevices();
+    }
+
+    AZ::RHI::ResultCode System::GetXRPhysicalDevice(AZ::RHI::XRPhysicalDeviceDescriptor* physicalDeviceDescriptor, int32_t index)
+    {
+        AZ_Error("XR", physicalDeviceDescriptor, "The descriptor is null");
+        if (physicalDeviceDescriptor)
+        {
+            return m_instance->GetXRPhysicalDevice(physicalDeviceDescriptor, index);
+        }
+
+        return AZ::RHI::ResultCode::Fail;
+    }
+
+    AZ::RHI::ResultCode System::CreateDevice(AZ::RHI::XRDeviceDescriptor* instanceDescriptor)
+    {
+        if (!m_device)
+        {
+            m_device = Factory::Get().CreateDevice();
+            AZ_Assert(m_device, "XR Device not created");
+            if (m_device->Init(Device::Descriptor{ m_validationMode, m_instance}) == AZ::RHI::ResultCode::Success)
+            {
+                return m_device->InitDeviceInternal(instanceDescriptor);
+            }
+        }
+        return AZ::RHI::ResultCode::Fail;
+    }
+
+    AZ::RHI::ResultCode System::CreateSession(AZ::RHI::XRSessionDescriptor* sessionDescriptor)
+    {
+        if (!m_session)
+        {
+            m_session = Factory::Get().CreateSession();
+            AZ_Assert(m_session, "Session not created");
+            AZ::RHI::ResultCode result = m_session->Init(Session::Descriptor{ m_validationMode, m_device, m_instance });
+            if (result == AZ::RHI::ResultCode::Success)
+            {
+                return m_session->InitInternal(sessionDescriptor);
+            }
+        }
+        return AZ::RHI::ResultCode::Fail;
+    }
+
+    AZ::RHI::ResultCode System::CreateSwapChain()
+    {
+        if (!m_swapChain)
+        {
+            m_swapChain = Factory::Get().CreateSwapChain();
+            AZ_Assert(m_swapChain, "XR SwapChain not created");
+            return m_swapChain->Init(SwapChain::Descriptor{ m_validationMode, m_instance, m_session, m_device });
+        }
+        return AZ::RHI::ResultCode::Fail;
+    }
+
+    AZ::RHI::ResultCode System::GetSwapChainImage(AZ::RHI::XRSwapChainDescriptor* swapchainDescriptor) const
+    {
+        AZ_Assert(m_swapChain, "SwapChain is null");
+        if (m_swapChain)
+        {
+            return m_swapChain->GetSwapChainImage(swapchainDescriptor);
+        }
+        return AZ::RHI::ResultCode::Fail;
+    }
+
+    AZ::u32 System::GetSwapChainWidth(AZ::u32 viewIndex) const
+    {
+        AZ_Assert(m_swapChain, "SwapChain is null");
+        if (m_swapChain)
+        {
+            return m_swapChain->GetSwapChainWidth(viewIndex);
+        }
+        return 0;
+    }
+
+    AZ::u32 System::GetSwapChainHeight(AZ::u32 viewIndex) const
+    {
+        AZ_Assert(m_swapChain, "SwapChain is null");
+        if (m_swapChain)
+        {
+            return m_swapChain->GetSwapChainHeight(viewIndex);
+        }
+        return 0;
+    }
+
+    void System::OnSystemTick()
+    {
+        m_session->PollEvents();
+        if (m_session->IsSessionRunning())
+        {
+            m_session->GetInput()->PollActions();
+        }
+    }
+    
+    void System::BeginFrame()
+    {
+        if (m_device && m_session && m_session->IsSessionRunning())
+        {
+            m_isInFrame = m_device->BeginFrame();
+        }
+    }
+
+    void System::EndFrame()
+    {
+        if (m_isInFrame)
+        {
+            m_device->EndFrame(m_swapChain);
+            m_isInFrame = false;
+        }
+    }
+
+    void System::AcquireSwapChainImage(AZ::u32 viewIndex)
+    {
+        if (m_isInFrame && m_device->ShouldRender())
+        {
+            m_device->AcquireSwapChainImage(viewIndex, m_swapChain.get());
+        }
+    }
+
+    AZ::u32 System::GetNumViews() const
+    {
+        return m_swapChain->GetNumViews();
+    }
+
+    AZ::u32 System::GetCurrentImageIndex(AZ::u32 viewIndex) const
+    {
+        SwapChain::View* viewSwapchain = m_swapChain->GetView(viewIndex);
+        return viewSwapchain->m_activeImageIndex;
+    }
+
+    bool System::ShouldRender() const
+    {
+        if (m_session->IsSessionRunning())
+        { 
+            return m_device->ShouldRender();
+        }
+        return false;
+    }
+
+    AZ::RPI::FovData System::GetViewFov(AZ::u32 viewIndex) const
+    {
+        return m_device->GetViewFov(viewIndex);
+    }
+
+    AZ::RPI::PoseData System::GetViewPose(AZ::u32 viewIndex) const
+    {
+        return m_device->GetViewPose(viewIndex);
+    }
+
+    AZ::RPI::PoseData System::GetControllerPose(AZ::u32 handIndex) const
+    {
+        if (m_session->IsSessionRunning())
+        {
+            return m_session->GetControllerPose(handIndex);
+        }
+        return AZ::RPI::PoseData();
+    }
+
+    float System::GetControllerScale(AZ::u32 handIndex) const
+    {
+        if (m_session->IsSessionRunning())
+        {
+            return m_session->GetControllerScale(handIndex);
+        }
+        return 1.0f;
+    }
+
+    AZ::RPI::PoseData System::GetViewFrontPose() const
+    {
+        if (m_session->IsSessionRunning())
+        {
+            return m_session->GetViewFrontPose();
+        }
+        return AZ::RPI::PoseData();
+    }
+
+    AZ::Matrix4x4 System::CreateProjectionOffset(float angleLeft, float angleRight, 
+                                                 float angleBottom, float angleTop, 
+                                                 float nearDist, float farDist)
+    {
+        return XR::CreateProjectionOffset(angleLeft, angleRight, angleBottom, angleTop, nearDist, farDist);
+    }
+
+    void System::Shutdown()
+    {
+        AZ::SystemTickBus::Handler::BusDisconnect();
+        m_instance = nullptr;
+        m_device = nullptr;
+    }
+}

+ 90 - 0
Gems/XR/Code/Source/XRSystemComponent.cpp

@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <XR/XRSystemComponent.h>
+#include <AzCore/Serialization/SerializeContext.h>
+#include <AzCore/Settings/SettingsRegistry.h>
+#include <Atom/RPI.Public/XR/XRRenderingInterface.h>
+#include <Atom/RHI/ValidationLayer.h>
+#include <Atom/RHI/FactoryManagerBus.h>
+#include <AzFramework/StringFunc/StringFunc.h>
+#include <AzFramework/API/ApplicationAPI.h>
+#include <AzFramework/CommandLine/CommandLine.h>
+
+static constexpr char OpenXREnableSetting[] = "/O3DE/Atom/OpenXREnable";
+
+namespace XR
+{
+    void SystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        provided.push_back(AZ_CRC_CE("XRSystemService"));
+    }
+
+    void SystemComponent::Reflect(AZ::ReflectContext* context)
+    {
+        if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext->Class<SystemComponent, AZ::Component>()->Version(1);
+        }
+    }
+
+    SystemComponent::SystemComponent()
+    {
+        m_xrSystem = aznew System();
+    }
+
+    void SystemComponent::Activate()
+    {
+        // Register XR system interface if openxr is enabled via command line or settings registry
+        if (IsOpenXREnabled())
+        {
+            //Get the validation mode
+            AZ::RHI::ValidationMode validationMode = AZ::RHI::ValidationMode::Disabled;
+            AZ::RHI::FactoryManagerBus::BroadcastResult(validationMode, &AZ::RHI::FactoryManagerRequest::DetermineValidationMode);
+
+            //Init the XRSystem
+            System::Descriptor descriptor;
+            descriptor.m_validationMode = validationMode;
+            m_xrSystem->Init(descriptor);
+
+            //Register xr system with RPI
+            AZ::RPI::XRRegisterInterface::Get()->RegisterXRInterface(m_xrSystem.get());
+        }
+    }
+
+    void SystemComponent::Deactivate()
+    {
+        m_xrSystem->Shutdown();
+    }
+
+    bool SystemComponent::IsOpenXREnabled()
+    {
+        const AzFramework::CommandLine* commandLine = nullptr;
+        AZStd::string commandLineValue;
+
+        //Check command line option(-openxr=enable)
+        AzFramework::ApplicationRequests::Bus::BroadcastResult(commandLine, &AzFramework::ApplicationRequests::GetApplicationCommandLine);
+        if (commandLine)
+        {
+            if (size_t switchCount = commandLine->GetNumSwitchValues("openxr"); switchCount > 0)
+            {
+                commandLineValue = commandLine->GetSwitchValue("openxr", switchCount - 1);
+            }
+        }
+        bool isOpenXREnabledViaCL = AzFramework::StringFunc::Equal(commandLineValue.c_str(), "enable");
+
+        //Check settings registry
+        AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get();
+        bool isOpenXREnabledViaSR = false;
+        if (settingsRegistry)
+        {
+            settingsRegistry->Get(isOpenXREnabledViaSR, OpenXREnableSetting);
+        }
+        return isOpenXREnabledViaSR || isOpenXREnabledViaCL;
+    }
+}

+ 47 - 0
Gems/XR/Code/Source/XRUtils.cpp

@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <XR/XRUtils.h>
+
+namespace XR
+{
+    AZ::Matrix4x4 CreateProjectionOffset(float angleLeft, float angleRight, float angleBottom, float angleTop, float nearDist, float farDist)
+    {
+        AZ::Matrix4x4 result;
+        AZ_MATH_ASSERT(nearDist > 0.0f, "Near plane distance must be greater than 0");
+        
+        const float left = tanf(angleLeft);
+        const float right = tanf(angleRight);
+        const float bottom = tanf(angleBottom);
+        const float top = tanf(angleTop);
+
+        const float invfn = 1.0f / (farDist - nearDist);
+        const float tanAngleWidth = right - left;
+        const float tanAngleHeight = (top - bottom);
+
+        //Stretch more horizontally and vertically
+        //Generate asymmetric or off-center projection matrix
+        //Right handed coord system as Openxr provides data in that system
+        //Handle the case where farDist is less than nearDist
+        if(farDist > nearDist)
+        { 
+            result.SetRow(0, 2.0f / tanAngleWidth, 0.0f, (left + right) / tanAngleWidth, 0.0f);
+            result.SetRow(1, 0.0f, 2.0f / tanAngleHeight, (top + bottom) / tanAngleHeight, 0.0f);
+            result.SetRow(2, 0.0f, 0.0f, -1 * (farDist + nearDist) * invfn, -2.0f * farDist * nearDist * invfn);
+            result.SetRow(3, 0.0f, 0.0f, -1.0f, 0.0f);
+        }
+        else
+        {
+            result.SetRow(0, 2.0f / tanAngleWidth, 0.0f, (left + right) / tanAngleWidth, 0.0f);
+            result.SetRow(1, 0.0f, 2.0f / tanAngleHeight, (top + bottom) / tanAngleHeight, 0.0f);
+            result.SetRow(2, 0.0f, 0.0f, -1.0f, -2.0f * nearDist);
+            result.SetRow(3, 0.0f, 0.0f, -1.0f, 0.0f);
+        }
+        return result;
+    }
+}

+ 32 - 0
Gems/XR/Code/xr_private_common_files.cmake

@@ -0,0 +1,32 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Include/XR/XRBase.h
+    Include/XR/XRDevice.h
+    Include/XR/XRFactory.h
+    Include/XR/XRInput.h
+    Include/XR/XRInstance.h
+    Include/XR/XRSession.h
+    Include/XR/XRSpace.h
+    Include/XR/XRSwapChain.h
+    Include/XR/XRSystem.h
+    Include/XR/XRSystemComponent.h
+    Include/XR/XRUtils.h
+    Include/XR/XRObject.h
+    Source/XRDevice.cpp
+    Source/XRFactory.cpp
+    Source/XRInput.cpp
+    Source/XRInstance.cpp
+    Source/XRSession.cpp
+    Source/XRSpace.cpp
+    Source/XRSwapChain.cpp
+    Source/XRSystem.cpp
+    Source/XRSystemComponent.cpp
+    Source/XRUtils.cpp
+)

+ 11 - 0
Gems/XR/Code/xr_private_common_shared_files.cmake

@@ -0,0 +1,11 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/XRModule.cpp
+)

+ 11 - 0
Gems/XR/Code/xr_stub_module.cmake

@@ -0,0 +1,11 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/Platform/Common/Unimplemented/ModuleStub_Unimplemented.cpp
+)

+ 19 - 0
Gems/XR/gem.json

@@ -0,0 +1,19 @@
+{
+    "gem_name": "XR",
+    "display_name": "XR",
+    "license": "Apache-2.0 Or MIT",
+    "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
+    "origin": "Open 3D Engine - o3de.org",
+    "origin_url": "https://github.com/o3de/o3de",
+    "type": "Code",
+    "summary": "XR",
+    "canonical_tags": [
+        "Gem"
+    ],
+    "user_tags": [],
+    "requirements": "",
+    "documentation_url": "",
+    "dependencies": [
+        "Atom_RPI"
+    ]
+}

二進制
Gems/XR/preview.png