# OpenVR SDK 2.5.1

Clients:
 * Include Transfer Time in Frame Timing, when using Steam Link

Drivers:
 * Include HMD Pose Prediction Time
 * Adjust behavior for GetFrameTiming
 * Add IVRIPCResourceManagerClient for Linux

[git-p4: depot-paths = "//vr/steamvr/sdk_release/": change = 8791766]
diff --git a/bin/linux32/libopenvr_api.so b/bin/linux32/libopenvr_api.so
index fd2a93b..40684ea 100755
--- a/bin/linux32/libopenvr_api.so
+++ b/bin/linux32/libopenvr_api.so
Binary files differ
diff --git a/bin/linux32/libopenvr_api.so.dbg b/bin/linux32/libopenvr_api.so.dbg
index 3073acf..7719a9f 100755
--- a/bin/linux32/libopenvr_api.so.dbg
+++ b/bin/linux32/libopenvr_api.so.dbg
Binary files differ
diff --git a/bin/linux64/libopenvr_api.so b/bin/linux64/libopenvr_api.so
index 1815915..bd18873 100755
--- a/bin/linux64/libopenvr_api.so
+++ b/bin/linux64/libopenvr_api.so
Binary files differ
diff --git a/bin/linux64/libopenvr_api.so.dbg b/bin/linux64/libopenvr_api.so.dbg
index bad58b9..9053e43 100755
--- a/bin/linux64/libopenvr_api.so.dbg
+++ b/bin/linux64/libopenvr_api.so.dbg
Binary files differ
diff --git a/bin/linuxarm64/libopenvr_api.so b/bin/linuxarm64/libopenvr_api.so
index 1712fdd..a07b4c2 100644
--- a/bin/linuxarm64/libopenvr_api.so
+++ b/bin/linuxarm64/libopenvr_api.so
Binary files differ
diff --git a/bin/linuxarm64/libopenvr_api.so.dbg b/bin/linuxarm64/libopenvr_api.so.dbg
index 7d6aa6d..8b4f5e9 100644
--- a/bin/linuxarm64/libopenvr_api.so.dbg
+++ b/bin/linuxarm64/libopenvr_api.so.dbg
Binary files differ
diff --git a/bin/linuxarm64/libopenvr_api_unity.so b/bin/linuxarm64/libopenvr_api_unity.so
index e51d7bf..74c3fe6 100644
--- a/bin/linuxarm64/libopenvr_api_unity.so
+++ b/bin/linuxarm64/libopenvr_api_unity.so
Binary files differ
diff --git a/bin/linuxarm64/libopenvr_api_unity.so.dbg b/bin/linuxarm64/libopenvr_api_unity.so.dbg
index f971ade..88a605e 100644
--- a/bin/linuxarm64/libopenvr_api_unity.so.dbg
+++ b/bin/linuxarm64/libopenvr_api_unity.so.dbg
Binary files differ
diff --git a/bin/win32/openvr_api.dll b/bin/win32/openvr_api.dll
index cfc8f4c..089a7ad 100644
--- a/bin/win32/openvr_api.dll
+++ b/bin/win32/openvr_api.dll
Binary files differ
diff --git a/bin/win32/openvr_api.dll.sig b/bin/win32/openvr_api.dll.sig
index 1e466aa..3474f91 100644
--- a/bin/win32/openvr_api.dll.sig
+++ b/bin/win32/openvr_api.dll.sig
Binary files differ
diff --git a/bin/win32/openvr_api.pdb b/bin/win32/openvr_api.pdb
index 0b35b03..973d8c9 100644
--- a/bin/win32/openvr_api.pdb
+++ b/bin/win32/openvr_api.pdb
Binary files differ
diff --git a/bin/win64/openvr_api.dll b/bin/win64/openvr_api.dll
index 2acefbf..5c70fd1 100644
--- a/bin/win64/openvr_api.dll
+++ b/bin/win64/openvr_api.dll
Binary files differ
diff --git a/bin/win64/openvr_api.dll.sig b/bin/win64/openvr_api.dll.sig
index 19883ac..a798204 100644
--- a/bin/win64/openvr_api.dll.sig
+++ b/bin/win64/openvr_api.dll.sig
Binary files differ
diff --git a/bin/win64/openvr_api.pdb b/bin/win64/openvr_api.pdb
index aaada65..d01a714 100644
--- a/bin/win64/openvr_api.pdb
+++ b/bin/win64/openvr_api.pdb
Binary files differ
diff --git a/codegen/openvr_capi.cpp.py b/codegen/openvr_capi.cpp.py
index b11a872..5cae996 100755
--- a/codegen/openvr_capi.cpp.py
+++ b/codegen/openvr_capi.cpp.py
@@ -42,8 +42,18 @@
 #include <stdlib.h>
 #include <assert.h>
 
-#include "../headers/openvr.h"
-#include "openvr_capi.h"
+#include "openvr.h"
+#include "ivrsystem.h"
+#include "ivrchaperone.h"
+#include "ivrchaperonesetup.h"
+#include "ivrcompositor.h"
+#include "ivroverlay.h"
+#include "ivrrendermodels.h"
+#include "ivrnotifications.h"
+#include "ivrblockqueue.h"
+
+#include "../vrclient/interface_adapters_client.h"
+#include "_dynamic_openvr_api_flat.h"
 
 class FnTableRegistration
 {
@@ -67,7 +77,12 @@
 
 import json
 import sys
-with open('../headers/openvr_api.json') as data_file:
+
+if len(sys.argv) != 2:
+	sys.exit(-1);
+json_path = sys.argv[1]
+
+with open(json_path) as data_file:
 	data = json.load(data_file)
 
 import api_shared
diff --git a/codegen/openvr_capi.h.py b/codegen/openvr_capi.h.py
index eafd098..8633a89 100755
--- a/codegen/openvr_capi.h.py
+++ b/codegen/openvr_capi.h.py
@@ -77,9 +77,11 @@
 #endif
 """)
 
+if len(sys.argv) != 2:
+	sys.exit(-1);
+json_path = sys.argv[1]
 
-
-data = api_shared.loadfile('../headers/openvr_api.json', 'vr')
+data = api_shared.loadfile(json_path, 'vr')
 converttype = api_shared.converttype
 striparraysuffix = api_shared.striparraysuffix
 structlist = api_shared.structlist
diff --git a/codegen/openvr_interop.cs.py b/codegen/openvr_interop.cs.py
index 4783a87..8731158 100755
--- a/codegen/openvr_interop.cs.py
+++ b/codegen/openvr_interop.cs.py
@@ -22,9 +22,11 @@
 {
 """)
 
+if len(sys.argv) != 2:
+	sys.exit(-1);
+json_path = sys.argv[1]
 
-
-data = api_shared.loadfile('../headers/openvr_api.json', 'vr')
+data = api_shared.loadfile(json_path, 'vr')
 converttype = api_shared.converttype
 structlist = api_shared.structlist
 typedeflist = api_shared.typedeflist
diff --git a/headers/openvr.h b/headers/openvr.h
index a37db14..336094b 100644
--- a/headers/openvr.h
+++ b/headers/openvr.h
@@ -16,8 +16,8 @@
 namespace vr
 {
 	static const uint32_t k_nSteamVRVersionMajor = 2;
-	static const uint32_t k_nSteamVRVersionMinor = 2;
-	static const uint32_t k_nSteamVRVersionBuild = 3;
+	static const uint32_t k_nSteamVRVersionMinor = 5;
+	static const uint32_t k_nSteamVRVersionBuild = 1;
 } // namespace vr
 
 // public_vrtypes.h
@@ -885,6 +885,11 @@
 	VREvent_DesktopMightBeVisible			= 536, // Sent when any known desktop related overlay is visible
 	VREvent_DesktopMightBeHidden			= 537, // Sent when all known desktop related overlays are hidden
 
+	VREvent_MutualSteamCapabilitiesChanged	= 538, // Sent when the set of capabilities common between both Steam and SteamVR have changed.
+
+	VREvent_OverlayCreated					= 539, // An OpenVR overlay of any sort was created. Data is overlay.
+	VREvent_OverlayDestroyed				= 540, // An OpenVR overlay of any sort was destroyed. Data is overlay.
+
 	VREvent_Notification_Shown				= 600,
 	VREvent_Notification_Hidden				= 601,
 	VREvent_Notification_BeginInteraction	= 602,
@@ -1647,6 +1652,7 @@
 	VRNotificationError_NotificationQueueFull = 101,
 	VRNotificationError_InvalidOverlayHandle = 102,
 	VRNotificationError_SystemWithUserValueAlreadyExists = 103,
+	VRNotificationError_ServiceUnavailable = 104,
 };
 
 
@@ -2014,22 +2020,22 @@
 /** Compositor frame timing reprojection flags. */
 const uint32_t VRCompositor_ReprojectionReason_Cpu = 0x01;
 const uint32_t VRCompositor_ReprojectionReason_Gpu = 0x02;
-const uint32_t VRCompositor_ReprojectionAsync = 0x04;	// This flag indicates the async reprojection mode is active,
+const uint32_t VRCompositor_ReprojectionAsync = 0x04;		// This flag indicates the async reprojection mode is active,
 															// but does not indicate if reprojection actually happened or not.
 															// Use the ReprojectionReason flags above to check if reprojection
 															// was actually applied (i.e. scene texture was reused).
 															// NumFramePresents > 1 also indicates the scene texture was reused,
 															// and also the number of times that it was presented in total.
 
-const uint32_t VRCompositor_ReprojectionMotion = 0x08;	// This flag indicates whether or not motion smoothing was triggered for this frame
+const uint32_t VRCompositor_ReprojectionMotion = 0x08;		// This flag indicates whether or not motion smoothing was triggered for this frame
 
-const uint32_t VRCompositor_PredictionMask = 0xF0;	// The runtime may predict more than one frame (up to four) ahead if
-															// it detects the application is taking too long to render. These two
+const uint32_t VRCompositor_PredictionMask = 0xF0;			// The runtime may predict more than one frame ahead if
+															// it detects the application is taking too long to render. These
 															// bits will contain the count of additional frames (normally zero).
 															// Use the VR_COMPOSITOR_ADDITIONAL_PREDICTED_FRAMES macro to read from
 															// the latest frame timing entry.
 
-const uint32_t VRCompositor_ThrottleMask = 0xF00;	// Number of frames the compositor is throttling the application.
+const uint32_t VRCompositor_ThrottleMask = 0xF00;			// Number of frames the compositor is throttling the application.
 															// Use the VR_COMPOSITOR_NUMBER_OF_THROTTLED_FRAMES macro to read from
 															// the latest frame timing entry.
 
@@ -2081,6 +2087,8 @@
 
 	uint32_t m_nNumVSyncsReadyForUse;
 	uint32_t m_nNumVSyncsToFirstView;
+
+	float m_flTransferLatencyMs;
 };
 #if defined(__linux__) || defined(__APPLE__)
 #pragma pack( pop )
@@ -2728,6 +2736,7 @@
 		VRSettingsError_ReadFailed = 3,
 		VRSettingsError_JsonParseFailed = 4,
 		VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set
+		VRSettingsError_AccessDenied = 6,
 	};
 
 	// The maximum length of a settings key
@@ -2869,6 +2878,7 @@
 	static const char * const k_pch_SteamVR_AdditionalFramesToPredict_Int32 = "additionalFramesToPredict";
 	static const char * const k_pch_SteamVR_WorldScale_Float = "worldScale";
 	static const char * const k_pch_SteamVR_FovScale_Int32 = "fovScale";
+	static const char * const k_pch_SteamVR_FovScaleLetterboxed_Bool = "fovScaleLetterboxed";
 	static const char * const k_pch_SteamVR_DisableAsyncReprojection_Bool = "disableAsync";
 	static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking";
 	static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "mirrorView";
@@ -3069,7 +3079,7 @@
 	static const char * const k_pch_Dashboard_StickyDashboard = "stickyDashboard";
 	static const char * const k_pch_Dashboard_AllowSteamOverlays_Bool = "allowSteamOverlays";
 	static const char * const k_pch_Dashboard_AllowVRGamepadUI_Bool = "allowVRGamepadUI";
-	static const char * const k_pch_Dashboard_AllowDesktopBPMWithVRGamepadUI_Bool = "allowDesktopBPMWithVRGamepadUI";
+	static const char * const k_pch_Dashboard_AllowVRGamepadUIViaGamescope_Bool = "allowVRGamepadUIViaGamescope";
 	static const char * const k_pch_Dashboard_SteamMatchesHMDFramerate = "steamMatchesHMDFramerate";
 
 	//-----------------------------------------------------------------------------
@@ -3184,13 +3194,13 @@
 	virtual bool GetPlayAreaSize( float *pSizeX, float *pSizeZ ) = 0;
 
 	/** Returns a quad describing the Play Area (formerly named Soft Bounds).
-	 * The corners form a rectangle. 
+	 * The corners form a rectangle.
 	 * Corners are in counter-clockwise order, starting at the front-right.
 	 * The positions are given relative to the standing origin.
 	 * The center of the rectangle is the center of the user's calibrated play space, not necessarily the standing
-	 * origin. 
+	 * origin.
 	 * The Play Area's forward direction goes from its center through the mid-point of a line drawn between the
-	 * first and second corner. 
+	 * first and second corner.
 	 * The quad lies on the XZ plane (height = 0y), with 2 sides parallel to the X-axis and two sides parallel
 	 * to the Z-axis of the user's calibrated Play Area. **/
 	virtual bool GetPlayAreaRect( HmdQuad_t *rect ) = 0;
@@ -4338,7 +4348,7 @@
 		/** Shows the dashboard. */
 		virtual void ShowDashboard( const char *pchOverlayToShow ) = 0;
 
-		/** Returns the tracked device that has the laser pointer in the dashboard */
+		/** Returns the tracked device index that has the laser pointer in the dashboard, or the last one that was used. */
 		virtual vr::TrackedDeviceIndex_t GetPrimaryDashboardDevice() = 0;
 
 		// ---------------------------------------------
@@ -5229,7 +5239,7 @@
 		virtual EVRInputError GetOriginTrackedDeviceInfo( VRInputValueHandle_t origin, InputOriginInfo_t *pOriginInfo, uint32_t unOriginInfoSize ) = 0;
 
 		/** Retrieves useful information about the bindings for an action */
-		virtual EVRInputError GetActionBindingInfo( VRActionHandle_t action, InputBindingInfo_t *pOriginInfo, uint32_t unBindingInfoSize, uint32_t unBindingInfoCount, uint32_t *punReturnedBindingInfoCount ) = 0;
+		virtual EVRInputError GetActionBindingInfo( VRActionHandle_t action, VR_ARRAY_COUNT( unBindingInfoCount ) InputBindingInfo_t *pOriginInfo, uint32_t unBindingInfoSize, uint32_t unBindingInfoCount, uint32_t *punReturnedBindingInfoCount ) = 0;
 
 		/** Shows the current binding for the action in-headset */
 		virtual EVRInputError ShowActionOrigins( VRActionSetHandle_t actionSetHandle, VRActionHandle_t ulActionHandle ) = 0;
diff --git a/headers/openvr_api.cs b/headers/openvr_api.cs
index d83bfc3..9b45997 100644
--- a/headers/openvr_api.cs
+++ b/headers/openvr_api.cs
@@ -1842,7 +1842,7 @@
 	internal _GetOriginTrackedDeviceInfo GetOriginTrackedDeviceInfo;
 
 	[UnmanagedFunctionPointer(CallingConvention.StdCall)]
-	internal delegate EVRInputError _GetActionBindingInfo(ulong action, ref InputBindingInfo_t pOriginInfo, uint unBindingInfoSize, uint unBindingInfoCount, ref uint punReturnedBindingInfoCount);
+	internal delegate EVRInputError _GetActionBindingInfo(ulong action, [In, Out] InputBindingInfo_t[] pOriginInfo, uint unBindingInfoSize, uint unBindingInfoCount, ref uint punReturnedBindingInfoCount);
 	[MarshalAs(UnmanagedType.FunctionPtr)]
 	internal _GetActionBindingInfo GetActionBindingInfo;
 
@@ -4271,10 +4271,10 @@
 		EVRInputError result = FnTable.GetOriginTrackedDeviceInfo(origin,ref pOriginInfo,unOriginInfoSize);
 		return result;
 	}
-	public EVRInputError GetActionBindingInfo(ulong action,ref InputBindingInfo_t pOriginInfo,uint unBindingInfoSize,uint unBindingInfoCount,ref uint punReturnedBindingInfoCount)
+	public EVRInputError GetActionBindingInfo(ulong action,InputBindingInfo_t [] pOriginInfo,uint unBindingInfoSize,ref uint punReturnedBindingInfoCount)
 	{
 		punReturnedBindingInfoCount = 0;
-		EVRInputError result = FnTable.GetActionBindingInfo(action,ref pOriginInfo,unBindingInfoSize,unBindingInfoCount,ref punReturnedBindingInfoCount);
+		EVRInputError result = FnTable.GetActionBindingInfo(action,pOriginInfo,unBindingInfoSize,(uint) pOriginInfo.Length,ref punReturnedBindingInfoCount);
 		return result;
 	}
 	public EVRInputError ShowActionOrigins(ulong actionSetHandle,ulong ulActionHandle)
@@ -5020,6 +5020,9 @@
 	VREvent_DashboardThumbChanged = 535,
 	VREvent_DesktopMightBeVisible = 536,
 	VREvent_DesktopMightBeHidden = 537,
+	VREvent_MutualSteamCapabilitiesChanged = 538,
+	VREvent_OverlayCreated = 539,
+	VREvent_OverlayDestroyed = 540,
 	VREvent_Notification_Shown = 600,
 	VREvent_Notification_Hidden = 601,
 	VREvent_Notification_BeginInteraction = 602,
@@ -5317,6 +5320,7 @@
 	NotificationQueueFull = 101,
 	InvalidOverlayHandle = 102,
 	SystemWithUserValueAlreadyExists = 103,
+	ServiceUnavailable = 104,
 }
 public enum EVRSkeletalMotionRange
 {
@@ -5861,6 +5865,7 @@
 	ReadFailed = 3,
 	JsonParseFailed = 4,
 	UnsetSettingHasNoDefault = 5,
+	AccessDenied = 6,
 }
 public enum EVRScreenshotError
 {
@@ -6559,6 +6564,7 @@
 	public TrackedDevicePose_t m_HmdPose;
 	public uint m_nNumVSyncsReadyForUse;
 	public uint m_nNumVSyncsToFirstView;
+	public float m_flTransferLatencyMs;
 }
 [StructLayout(LayoutKind.Sequential)] public struct Compositor_BenchmarkResults
 {
@@ -7810,6 +7816,7 @@
 	public const string k_pch_SteamVR_AdditionalFramesToPredict_Int32 = "additionalFramesToPredict";
 	public const string k_pch_SteamVR_WorldScale_Float = "worldScale";
 	public const string k_pch_SteamVR_FovScale_Int32 = "fovScale";
+	public const string k_pch_SteamVR_FovScaleLetterboxed_Bool = "fovScaleLetterboxed";
 	public const string k_pch_SteamVR_DisableAsyncReprojection_Bool = "disableAsync";
 	public const string k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking";
 	public const string k_pch_SteamVR_DefaultMirrorView_Int32 = "mirrorView";
@@ -7968,7 +7975,7 @@
 	public const string k_pch_Dashboard_StickyDashboard = "stickyDashboard";
 	public const string k_pch_Dashboard_AllowSteamOverlays_Bool = "allowSteamOverlays";
 	public const string k_pch_Dashboard_AllowVRGamepadUI_Bool = "allowVRGamepadUI";
-	public const string k_pch_Dashboard_AllowDesktopBPMWithVRGamepadUI_Bool = "allowDesktopBPMWithVRGamepadUI";
+	public const string k_pch_Dashboard_AllowVRGamepadUIViaGamescope_Bool = "allowVRGamepadUIViaGamescope";
 	public const string k_pch_Dashboard_SteamMatchesHMDFramerate = "steamMatchesHMDFramerate";
 	public const string k_pch_modelskin_Section = "modelskins";
 	public const string k_pch_Driver_Enable_Bool = "enable";
diff --git a/headers/openvr_api.json b/headers/openvr_api.json
index ca3cbfc..e2f089f 100644
--- a/headers/openvr_api.json
+++ b/headers/openvr_api.json
@@ -463,6 +463,9 @@
 	,{"name": "VREvent_DashboardThumbChanged","value": "535"}
 	,{"name": "VREvent_DesktopMightBeVisible","value": "536"}
 	,{"name": "VREvent_DesktopMightBeHidden","value": "537"}
+	,{"name": "VREvent_MutualSteamCapabilitiesChanged","value": "538"}
+	,{"name": "VREvent_OverlayCreated","value": "539"}
+	,{"name": "VREvent_OverlayDestroyed","value": "540"}
 	,{"name": "VREvent_Notification_Shown","value": "600"}
 	,{"name": "VREvent_Notification_Hidden","value": "601"}
 	,{"name": "VREvent_Notification_BeginInteraction","value": "602"}
@@ -744,6 +747,7 @@
 	,{"name": "VRNotificationError_NotificationQueueFull","value": "101"}
 	,{"name": "VRNotificationError_InvalidOverlayHandle","value": "102"}
 	,{"name": "VRNotificationError_SystemWithUserValueAlreadyExists","value": "103"}
+	,{"name": "VRNotificationError_ServiceUnavailable","value": "104"}
 ]}
 ,	{"enumname": "vr::EVRSkeletalMotionRange","values": [ 
 	{"name": "VRSkeletalMotionRange_WithController","value": "0"}
@@ -1253,6 +1257,7 @@
 	,{"name": "VRSettingsError_ReadFailed","value": "3"}
 	,{"name": "VRSettingsError_JsonParseFailed","value": "4"}
 	,{"name": "VRSettingsError_UnsetSettingHasNoDefault","value": "5"}
+	,{"name": "VRSettingsError_AccessDenied","value": "6"}
 ]}
 ,	{"enumname": "vr::EVRScreenshotError","values": [ 
 	{"name": "VRScreenshotError_None","value": "0"}
@@ -1565,6 +1570,8 @@
 ,{
 	"constname": "k_pch_SteamVR_FovScale_Int32","consttype": "const char *const", "constval": "fovScale"}
 ,{
+	"constname": "k_pch_SteamVR_FovScaleLetterboxed_Bool","consttype": "const char *const", "constval": "fovScaleLetterboxed"}
+,{
 	"constname": "k_pch_SteamVR_DisableAsyncReprojection_Bool","consttype": "const char *const", "constval": "disableAsync"}
 ,{
 	"constname": "k_pch_SteamVR_ForceFadeOnBadTracking_Bool","consttype": "const char *const", "constval": "forceFadeOnBadTracking"}
@@ -1881,7 +1888,7 @@
 ,{
 	"constname": "k_pch_Dashboard_AllowVRGamepadUI_Bool","consttype": "const char *const", "constval": "allowVRGamepadUI"}
 ,{
-	"constname": "k_pch_Dashboard_AllowDesktopBPMWithVRGamepadUI_Bool","consttype": "const char *const", "constval": "allowDesktopBPMWithVRGamepadUI"}
+	"constname": "k_pch_Dashboard_AllowVRGamepadUIViaGamescope_Bool","consttype": "const char *const", "constval": "allowVRGamepadUIViaGamescope"}
 ,{
 	"constname": "k_pch_Dashboard_SteamMatchesHMDFramerate","consttype": "const char *const", "constval": "steamMatchesHMDFramerate"}
 ,{
@@ -2350,7 +2357,8 @@
 { "fieldname": "m_flCompositorRenderStartMs", "fieldtype": "float"},
 { "fieldname": "m_HmdPose", "fieldtype": "vr::TrackedDevicePose_t"},
 { "fieldname": "m_nNumVSyncsReadyForUse", "fieldtype": "uint32_t"},
-{ "fieldname": "m_nNumVSyncsToFirstView", "fieldtype": "uint32_t"}]}
+{ "fieldname": "m_nNumVSyncsToFirstView", "fieldtype": "uint32_t"},
+{ "fieldname": "m_flTransferLatencyMs", "fieldtype": "float"}]}
 ,{"struct": "vr::Compositor_BenchmarkResults","fields": [
 { "fieldname": "m_flMegaPixelsPerSecond", "fieldtype": "float"},
 { "fieldname": "m_flHmdRecommendedMegaPixelsPerSecond", "fieldtype": "float"}]}
@@ -5560,7 +5568,7 @@
 	"returntype": "vr::EVRInputError",
 	"params": [ 
 {	"paramname": "action" ,"paramtype": "vr::VRActionHandle_t"},
-{	"paramname": "pOriginInfo" ,"paramtype": "struct vr::InputBindingInfo_t *"},
+{	"paramname": "pOriginInfo" ,"array_count": "unBindingInfoCount" ,"paramtype": "struct vr::InputBindingInfo_t *"},
 {	"paramname": "unBindingInfoSize" ,"paramtype": "uint32_t"},
 {	"paramname": "unBindingInfoCount" ,"paramtype": "uint32_t"},
 {	"paramname": "punReturnedBindingInfoCount" ,"paramtype": "uint32_t *"}
diff --git a/headers/openvr_capi.h b/headers/openvr_capi.h
index 49fd4a7..4a0de42 100644
--- a/headers/openvr_capi.h
+++ b/headers/openvr_capi.h
@@ -183,6 +183,7 @@
 static const char * k_pch_SteamVR_AdditionalFramesToPredict_Int32 = "additionalFramesToPredict";
 static const char * k_pch_SteamVR_WorldScale_Float = "worldScale";
 static const char * k_pch_SteamVR_FovScale_Int32 = "fovScale";
+static const char * k_pch_SteamVR_FovScaleLetterboxed_Bool = "fovScaleLetterboxed";
 static const char * k_pch_SteamVR_DisableAsyncReprojection_Bool = "disableAsync";
 static const char * k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking";
 static const char * k_pch_SteamVR_DefaultMirrorView_Int32 = "mirrorView";
@@ -341,7 +342,7 @@
 static const char * k_pch_Dashboard_StickyDashboard = "stickyDashboard";
 static const char * k_pch_Dashboard_AllowSteamOverlays_Bool = "allowSteamOverlays";
 static const char * k_pch_Dashboard_AllowVRGamepadUI_Bool = "allowVRGamepadUI";
-static const char * k_pch_Dashboard_AllowDesktopBPMWithVRGamepadUI_Bool = "allowDesktopBPMWithVRGamepadUI";
+static const char * k_pch_Dashboard_AllowVRGamepadUIViaGamescope_Bool = "allowVRGamepadUIViaGamescope";
 static const char * k_pch_Dashboard_SteamMatchesHMDFramerate = "steamMatchesHMDFramerate";
 static const char * k_pch_modelskin_Section = "modelskins";
 static const char * k_pch_Driver_Enable_Bool = "enable";
@@ -884,6 +885,9 @@
 	EVREventType_VREvent_DashboardThumbChanged = 535,
 	EVREventType_VREvent_DesktopMightBeVisible = 536,
 	EVREventType_VREvent_DesktopMightBeHidden = 537,
+	EVREventType_VREvent_MutualSteamCapabilitiesChanged = 538,
+	EVREventType_VREvent_OverlayCreated = 539,
+	EVREventType_VREvent_OverlayDestroyed = 540,
 	EVREventType_VREvent_Notification_Shown = 600,
 	EVREventType_VREvent_Notification_Hidden = 601,
 	EVREventType_VREvent_Notification_BeginInteraction = 602,
@@ -1197,6 +1201,7 @@
 	EVRNotificationError_VRNotificationError_NotificationQueueFull = 101,
 	EVRNotificationError_VRNotificationError_InvalidOverlayHandle = 102,
 	EVRNotificationError_VRNotificationError_SystemWithUserValueAlreadyExists = 103,
+	EVRNotificationError_VRNotificationError_ServiceUnavailable = 104,
 } EVRNotificationError;
 
 typedef enum EVRSkeletalMotionRange
@@ -1776,6 +1781,7 @@
 	EVRSettingsError_VRSettingsError_ReadFailed = 3,
 	EVRSettingsError_VRSettingsError_JsonParseFailed = 4,
 	EVRSettingsError_VRSettingsError_UnsetSettingHasNoDefault = 5,
+	EVRSettingsError_VRSettingsError_AccessDenied = 6,
 } EVRSettingsError;
 
 typedef enum EVRScreenshotError
@@ -2383,6 +2389,7 @@
 	TrackedDevicePose_t m_HmdPose;
 	uint32_t m_nNumVSyncsReadyForUse;
 	uint32_t m_nNumVSyncsToFirstView;
+	float m_flTransferLatencyMs;
 } Compositor_FrameTiming;
 
 typedef struct Compositor_BenchmarkResults
diff --git a/headers/openvr_driver.h b/headers/openvr_driver.h
index c473831..257ac6c 100644
--- a/headers/openvr_driver.h
+++ b/headers/openvr_driver.h
@@ -16,8 +16,8 @@
 namespace vr
 {
 	static const uint32_t k_nSteamVRVersionMajor = 2;
-	static const uint32_t k_nSteamVRVersionMinor = 2;
-	static const uint32_t k_nSteamVRVersionBuild = 3;
+	static const uint32_t k_nSteamVRVersionMinor = 5;
+	static const uint32_t k_nSteamVRVersionBuild = 1;
 } // namespace vr
 
 // public_vrtypes.h
@@ -885,6 +885,11 @@
 	VREvent_DesktopMightBeVisible			= 536, // Sent when any known desktop related overlay is visible
 	VREvent_DesktopMightBeHidden			= 537, // Sent when all known desktop related overlays are hidden
 
+	VREvent_MutualSteamCapabilitiesChanged	= 538, // Sent when the set of capabilities common between both Steam and SteamVR have changed.
+
+	VREvent_OverlayCreated					= 539, // An OpenVR overlay of any sort was created. Data is overlay.
+	VREvent_OverlayDestroyed				= 540, // An OpenVR overlay of any sort was destroyed. Data is overlay.
+
 	VREvent_Notification_Shown				= 600,
 	VREvent_Notification_Hidden				= 601,
 	VREvent_Notification_BeginInteraction	= 602,
@@ -1647,6 +1652,7 @@
 	VRNotificationError_NotificationQueueFull = 101,
 	VRNotificationError_InvalidOverlayHandle = 102,
 	VRNotificationError_SystemWithUserValueAlreadyExists = 103,
+	VRNotificationError_ServiceUnavailable = 104,
 };
 
 
@@ -2014,22 +2020,22 @@
 /** Compositor frame timing reprojection flags. */
 const uint32_t VRCompositor_ReprojectionReason_Cpu = 0x01;
 const uint32_t VRCompositor_ReprojectionReason_Gpu = 0x02;
-const uint32_t VRCompositor_ReprojectionAsync = 0x04;	// This flag indicates the async reprojection mode is active,
+const uint32_t VRCompositor_ReprojectionAsync = 0x04;		// This flag indicates the async reprojection mode is active,
 															// but does not indicate if reprojection actually happened or not.
 															// Use the ReprojectionReason flags above to check if reprojection
 															// was actually applied (i.e. scene texture was reused).
 															// NumFramePresents > 1 also indicates the scene texture was reused,
 															// and also the number of times that it was presented in total.
 
-const uint32_t VRCompositor_ReprojectionMotion = 0x08;	// This flag indicates whether or not motion smoothing was triggered for this frame
+const uint32_t VRCompositor_ReprojectionMotion = 0x08;		// This flag indicates whether or not motion smoothing was triggered for this frame
 
-const uint32_t VRCompositor_PredictionMask = 0xF0;	// The runtime may predict more than one frame (up to four) ahead if
-															// it detects the application is taking too long to render. These two
+const uint32_t VRCompositor_PredictionMask = 0xF0;			// The runtime may predict more than one frame ahead if
+															// it detects the application is taking too long to render. These
 															// bits will contain the count of additional frames (normally zero).
 															// Use the VR_COMPOSITOR_ADDITIONAL_PREDICTED_FRAMES macro to read from
 															// the latest frame timing entry.
 
-const uint32_t VRCompositor_ThrottleMask = 0xF00;	// Number of frames the compositor is throttling the application.
+const uint32_t VRCompositor_ThrottleMask = 0xF00;			// Number of frames the compositor is throttling the application.
 															// Use the VR_COMPOSITOR_NUMBER_OF_THROTTLED_FRAMES macro to read from
 															// the latest frame timing entry.
 
@@ -2081,6 +2087,8 @@
 
 	uint32_t m_nNumVSyncsReadyForUse;
 	uint32_t m_nNumVSyncsToFirstView;
+
+	float m_flTransferLatencyMs;
 };
 #if defined(__linux__) || defined(__APPLE__)
 #pragma pack( pop )
@@ -2320,6 +2328,7 @@
 		VRSettingsError_ReadFailed = 3,
 		VRSettingsError_JsonParseFailed = 4,
 		VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set
+		VRSettingsError_AccessDenied = 6,
 	};
 
 	// The maximum length of a settings key
@@ -2461,6 +2470,7 @@
 	static const char * const k_pch_SteamVR_AdditionalFramesToPredict_Int32 = "additionalFramesToPredict";
 	static const char * const k_pch_SteamVR_WorldScale_Float = "worldScale";
 	static const char * const k_pch_SteamVR_FovScale_Int32 = "fovScale";
+	static const char * const k_pch_SteamVR_FovScaleLetterboxed_Bool = "fovScaleLetterboxed";
 	static const char * const k_pch_SteamVR_DisableAsyncReprojection_Bool = "disableAsync";
 	static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking";
 	static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "mirrorView";
@@ -2661,7 +2671,7 @@
 	static const char * const k_pch_Dashboard_StickyDashboard = "stickyDashboard";
 	static const char * const k_pch_Dashboard_AllowSteamOverlays_Bool = "allowSteamOverlays";
 	static const char * const k_pch_Dashboard_AllowVRGamepadUI_Bool = "allowVRGamepadUI";
-	static const char * const k_pch_Dashboard_AllowDesktopBPMWithVRGamepadUI_Bool = "allowDesktopBPMWithVRGamepadUI";
+	static const char * const k_pch_Dashboard_AllowVRGamepadUIViaGamescope_Bool = "allowVRGamepadUIViaGamescope";
 	static const char * const k_pch_Dashboard_SteamMatchesHMDFramerate = "steamMatchesHMDFramerate";
 
 	//-----------------------------------------------------------------------------
@@ -2969,6 +2979,9 @@
 
 			// Hmd pose used to render this layer.
 			vr::HmdMatrix34_t mHmdPose;
+
+			// Time in seconds from now that mHmdPose was predicted to.
+			float flHmdPosePredictionTimeInSecondsFromNow;
 		};
 		virtual void SubmitLayer( const SubmitLayerPerEye_t( &perEye )[ 2 ] ) {}
 
@@ -2985,10 +2998,15 @@
 		virtual void PostPresent( const Throttling_t *pThrottling ) {}
 
 		/** Called to get additional frame timing stats from driver.  Check m_nSize for versioning (new members will be added to end only). */
-		virtual void GetFrameTiming( DriverDirectMode_FrameTiming *pFrameTiming ) {}
+		virtual void GetFrameTiming( DriverDirectMode_FrameTiming *pFrameTiming )
+		{
+			/** VRCompositor_ReprojectionMotion_XXX flags get passed in, and since these overlap with VRCompositor_ThrottleMask, they need
+			* to be cleared out if this function isn't implemented; otherwise, those settings will get interpreted as throttling. */
+			pFrameTiming->m_nReprojectionFlags = 0;
+		}
 	};
 
-	static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_008";
+	static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_009";
 
 }
 
@@ -4126,6 +4144,44 @@
 
 } // namespace vr
 
+// ivripcresourcemanagerclient.h
+
+namespace vr
+{
+
+// -----------------------------------------------------------------------------
+// Purpose: Interact with the IPCResourceManager
+// -----------------------------------------------------------------------------
+class IVRIPCResourceManagerClient
+{
+public:
+	/** Create a new tracked Vulkan Image
+	 *
+	 * nImageFormat: in VkFormat
+	 */
+	virtual bool NewSharedVulkanImage( uint32_t nImageFormat, uint32_t nWidth, uint32_t nHeight, bool bRenderable, bool bMappable, bool bComputeAccess, uint32_t unMipLevels, uint32_t unArrayLayerCount, vr::SharedTextureHandle_t *pSharedHandle ) = 0;
+
+	/** Create a new tracked Vulkan Buffer */
+	virtual bool NewSharedVulkanBuffer( size_t nSize, uint32_t nUsageFlags, vr::SharedTextureHandle_t *pSharedHandle ) = 0;
+
+	/** Create a new tracked Vulkan Semaphore */
+	virtual bool NewSharedVulkanSemaphore( vr::SharedTextureHandle_t *pSharedHandle ) = 0;
+
+	/** Grab a reference to hSharedHandle, and optionally generate a new IPC handle if pNewIpcHandle is not nullptr  */
+	virtual bool RefResource( vr::SharedTextureHandle_t hSharedHandle, uint64_t *pNewIpcHandle ) = 0;
+
+	/** Drop a reference to hSharedHandle */
+	virtual bool UnrefResource( vr::SharedTextureHandle_t hSharedHandle ) = 0;
+
+protected:
+	/** Non-deletable */
+	virtual ~IVRIPCResourceManagerClient() {};
+};
+
+static const char *IVRIPCResourceManagerClient_Version = "IVRIPCResourceManagerClient_001";
+
+}
+
 
 
 namespace vr
@@ -4144,6 +4200,7 @@
 		IVRDriverManager_Version,
 		IVRResources_Version,
 		IVRCompositorPluginProvider_Version,
+		IVRIPCResourceManagerClient_Version,
 		nullptr
 	};
 
@@ -4292,6 +4349,16 @@
 			return m_pVRDriverSpatialAnchors;
 		}
 
+		IVRIPCResourceManagerClient *VRIPCResourceManager()
+		{
+			if ( m_pVRIPCResourceManager == nullptr )
+			{
+				EVRInitError eError;
+				m_pVRIPCResourceManager = ( IVRIPCResourceManagerClient * )VRDriverContext()->GetGenericInterface( IVRIPCResourceManagerClient_Version, &eError );
+			}
+			return m_pVRIPCResourceManager;
+		}
+
 	private:
 		CVRPropertyHelpers		m_propertyHelpers;
 		CVRHiddenAreaHelpers	m_hiddenAreaHelpers;
@@ -4307,6 +4374,7 @@
 		IVRDriverInput			*m_pVRDriverInput;
 		IVRIOBuffer				*m_pVRIOBuffer;
 		IVRDriverSpatialAnchors *m_pVRDriverSpatialAnchors;
+		IVRIPCResourceManagerClient *m_pVRIPCResourceManager;
 	};
 
 	inline COpenVRDriverContext &OpenVRInternal_ModuleServerDriverContext()
@@ -4329,6 +4397,7 @@
 	inline IVRDriverInput *VR_CALLTYPE VRDriverInput() { return OpenVRInternal_ModuleServerDriverContext().VRDriverInput(); }
 	inline IVRIOBuffer *VR_CALLTYPE VRIOBuffer() { return OpenVRInternal_ModuleServerDriverContext().VRIOBuffer(); }
 	inline IVRDriverSpatialAnchors *VR_CALLTYPE VRDriverSpatialAnchors() { return OpenVRInternal_ModuleServerDriverContext().VRDriverSpatialAnchors(); }
+	inline IVRIPCResourceManagerClient *VR_CALLTYPE VRIPCResourceManager() { return OpenVRInternal_ModuleServerDriverContext().VRIPCResourceManager(); }
 
 	inline void COpenVRDriverContext::Clear()
 	{
@@ -4343,11 +4412,13 @@
 		m_pVRDriverInput = nullptr;
 		m_pVRIOBuffer = nullptr;
 		m_pVRDriverSpatialAnchors = nullptr;
+		m_pVRIPCResourceManager = nullptr;
 	}
 
 	inline EVRInitError COpenVRDriverContext::InitServer()
 	{
 		Clear();
+		// VRIPCResourceManager initialized async.
 		if ( !VRServerDriverHost()
 			|| !VRSettings()
 			|| !VRProperties()
diff --git a/lib/linuxarm64/libopenvr_api_unity.so b/lib/linuxarm64/libopenvr_api_unity.so
index f971ade..88a605e 100644
--- a/lib/linuxarm64/libopenvr_api_unity.so
+++ b/lib/linuxarm64/libopenvr_api_unity.so
Binary files differ
diff --git a/samples/bin/linux32/libopenvr_api.so b/samples/bin/linux32/libopenvr_api.so
index fd2a93b..40684ea 100644
--- a/samples/bin/linux32/libopenvr_api.so
+++ b/samples/bin/linux32/libopenvr_api.so
Binary files differ
diff --git a/samples/bin/linux64/libopenvr_api.so b/samples/bin/linux64/libopenvr_api.so
index 1815915..bd18873 100644
--- a/samples/bin/linux64/libopenvr_api.so
+++ b/samples/bin/linux64/libopenvr_api.so
Binary files differ
diff --git a/samples/bin/linuxarm64/libopenvr_api.so b/samples/bin/linuxarm64/libopenvr_api.so
index 1712fdd..a07b4c2 100644
--- a/samples/bin/linuxarm64/libopenvr_api.so
+++ b/samples/bin/linuxarm64/libopenvr_api.so
Binary files differ
diff --git a/samples/bin/win32/hmd_opencv_sandbox.exe b/samples/bin/win32/hmd_opencv_sandbox.exe
index 27baf63..c4f8785 100755
--- a/samples/bin/win32/hmd_opencv_sandbox.exe
+++ b/samples/bin/win32/hmd_opencv_sandbox.exe
Binary files differ
diff --git a/samples/bin/win32/openvr_api.dll b/samples/bin/win32/openvr_api.dll
index cfc8f4c..089a7ad 100644
--- a/samples/bin/win32/openvr_api.dll
+++ b/samples/bin/win32/openvr_api.dll
Binary files differ
diff --git a/samples/bin/win64/hmd_opencv_sandbox.exe b/samples/bin/win64/hmd_opencv_sandbox.exe
index b0ddde0..72a3307 100755
--- a/samples/bin/win64/hmd_opencv_sandbox.exe
+++ b/samples/bin/win64/hmd_opencv_sandbox.exe
Binary files differ
diff --git a/samples/bin/win64/openvr_api.dll b/samples/bin/win64/openvr_api.dll
index 2acefbf..5c70fd1 100644
--- a/samples/bin/win64/openvr_api.dll
+++ b/samples/bin/win64/openvr_api.dll
Binary files differ