Update OpenVR to 1.0.18 draft
authorKearwood Gilbert <kgilbert@mozilla.com>
Fri, 04 May 2018 16:31:58 -0700
changeset 792191 99401fc3b296a50ea82b7acb6ba978398bea2c5c
parent 792086 2d95d70298e248161b629ef1d0d57049c0b62d71
push id109039
push userkgilbert@mozilla.com
push dateMon, 07 May 2018 21:08:16 +0000
milestone62.0a1
Update OpenVR to 1.0.18 MozReview-Commit-ID: HnsMlUukB6z
gfx/vr/openvr/README.mozilla
gfx/vr/openvr/headers/openvr.h
gfx/vr/openvr/src/hmderrors_public.cpp
gfx/vr/openvr/src/openvr_api_public.cpp
gfx/vr/openvr/src/pathtools_public.cpp
gfx/vr/openvr/src/pathtools_public.h
gfx/vr/openvr/src/strtools_public.cpp
gfx/vr/openvr/src/strtools_public.h
gfx/vr/openvr/src/vrpathregistry_public.cpp
--- a/gfx/vr/openvr/README.mozilla
+++ b/gfx/vr/openvr/README.mozilla
@@ -1,9 +1,9 @@
-This directory contains files from the OpenVR SDK, version 1.0.8.
+This directory contains files from the OpenVR SDK, version 1.0.14.
 
 This SDK contains the OpenVR API interface headers and functions to load the
 OpenVR runtime libraries which actually implement the functionality. The
 loading functions parse a .json file in a pre-defined location on the
 end-user's machine to get details used to bind the correct runtime library.
 The OpenVR implementation ensures forward and backwards compatibility as of
 the current version.
 
--- a/gfx/vr/openvr/headers/openvr.h
+++ b/gfx/vr/openvr/headers/openvr.h
@@ -31,17 +31,17 @@ namespace vr
 
 typedef void* glSharedTextureHandle_t;
 typedef int32_t glInt_t;
 typedef uint32_t glUInt_t;
 
 // right-handed system
 // +y is up
 // +x is to the right
-// -z is going away from you
+// -z is forward
 // Distance unit is  meters
 struct HmdMatrix34_t
 {
 	float m[3][4];
 };
 
 struct HmdMatrix44_t
 {
@@ -107,16 +107,18 @@ enum EVREye
 
 enum ETextureType
 {
 	TextureType_DirectX = 0, // Handle is an ID3D11Texture
 	TextureType_OpenGL = 1,  // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags
 	TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure
 	TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef
 	TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure
+	TextureType_DXGISharedHandle = 5, // Handle is a HANDLE DXGI share handle, only supported for Overlay render targets. 
+									  // this texture is used directly by our renderer, so only perform atomic (copyresource or resolve) on it
 };
 
 enum EColorSpace
 {
 	ColorSpace_Auto = 0,	// Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'.  This mirrors the DXGI formats which have _SRGB variants.
 	ColorSpace_Gamma = 1,	// Texture data can be displayed directly on the display without any conversion (a.k.a. display native format).
 	ColorSpace_Linear = 2,	// Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm.
 };
@@ -146,17 +148,17 @@ enum ETrackingResult
 typedef uint32_t DriverId_t;
 static const uint32_t k_nDriverNone = 0xFFFFFFFF;
 
 static const uint32_t k_unMaxDriverDebugResponseSize = 32768;
 
 /** Used to pass device IDs to API calls */
 typedef uint32_t TrackedDeviceIndex_t;
 static const uint32_t k_unTrackedDeviceIndex_Hmd = 0;
-static const uint32_t k_unMaxTrackedDeviceCount = 16;
+static const uint32_t k_unMaxTrackedDeviceCount = 64;
 static const uint32_t k_unTrackedDeviceIndexOther = 0xFFFFFFFE;
 static const uint32_t k_unTrackedDeviceIndexInvalid = 0xFFFFFFFF;
 
 /** Describes what kind of object is being tracked at a given ID */
 enum ETrackedDeviceClass
 {
 	TrackedDeviceClass_Invalid = 0,				// the ID was not valid.
 	TrackedDeviceClass_HMD = 1,					// Head-Mounted Displays
@@ -168,16 +170,18 @@ enum ETrackedDeviceClass
 
 
 /** Describes what specific role associated with a tracked device */
 enum ETrackedControllerRole
 {
 	TrackedControllerRole_Invalid = 0,					// Invalid value for controller type
 	TrackedControllerRole_LeftHand = 1,					// Tracked device associated with the left hand
 	TrackedControllerRole_RightHand = 2,				// Tracked device associated with the right hand
+	TrackedControllerRole_OptOut = 3,					// Tracked device is opting out of left/right hand selection
+	TrackedControllerRole_Max = 4
 };
 
 
 /** describes a single pose for a tracked object */
 struct TrackedDevicePose_t
 {
 	HmdMatrix34_t mDeviceToAbsoluteTracking;
 	HmdVector3_t vVelocity;				// velocity in tracker space in m/s
@@ -194,36 +198,47 @@ struct TrackedDevicePose_t
 * for the poses it is requesting */
 enum ETrackingUniverseOrigin
 {
 	TrackingUniverseSeated = 0,		// Poses are provided relative to the seated zero pose
 	TrackingUniverseStanding = 1,	// Poses are provided relative to the safe bounds configured by the user
 	TrackingUniverseRawAndUncalibrated = 2,	// Poses are provided in the coordinate system defined by the driver.  It has Y up and is unified for devices of the same driver. You usually don't want this one.
 };
 
+typedef uint64_t WebConsoleHandle_t;
+#define INVALID_WEB_CONSOLE_HANDLE	((vr::WebConsoleHandle_t)0)
+
 // Refers to a single container of properties
 typedef uint64_t PropertyContainerHandle_t;
 typedef uint32_t PropertyTypeTag_t;
 
 static const PropertyContainerHandle_t k_ulInvalidPropertyContainer = 0;
 static const PropertyTypeTag_t k_unInvalidPropertyTag = 0;
 
+typedef PropertyContainerHandle_t DriverHandle_t;
+static const PropertyContainerHandle_t k_ulInvalidDriverHandle = 0;
+
 // Use these tags to set/get common types as struct properties
 static const PropertyTypeTag_t k_unFloatPropertyTag = 1;
 static const PropertyTypeTag_t k_unInt32PropertyTag = 2;
 static const PropertyTypeTag_t k_unUint64PropertyTag = 3;
 static const PropertyTypeTag_t k_unBoolPropertyTag = 4;
 static const PropertyTypeTag_t k_unStringPropertyTag = 5;
 
 static const PropertyTypeTag_t k_unHmdMatrix34PropertyTag = 20;
 static const PropertyTypeTag_t k_unHmdMatrix44PropertyTag = 21;
 static const PropertyTypeTag_t k_unHmdVector3PropertyTag = 22;
 static const PropertyTypeTag_t k_unHmdVector4PropertyTag = 23;
 
 static const PropertyTypeTag_t k_unHiddenAreaPropertyTag = 30;
+static const PropertyTypeTag_t k_unPathHandleInfoTag = 31;
+static const PropertyTypeTag_t k_unActionPropertyTag = 32;
+static const PropertyTypeTag_t k_unInputValuePropertyTag = 33;
+static const PropertyTypeTag_t k_unWildcardPropertyTag = 34;
+static const PropertyTypeTag_t k_unHapticVibrationPropertyTag = 35;
 
 static const PropertyTypeTag_t k_unOpenVRInternalReserved_Start = 1000;
 static const PropertyTypeTag_t k_unOpenVRInternalReserved_End = 10000;
 
 
 /** Each entry in this enum represents a property that can be retrieved about a
 * tracked device. Many fields are only valid for one ETrackedDeviceClass. */
 enum ETrackedDeviceProperty
@@ -262,16 +277,21 @@ enum ETrackedDeviceProperty
 	Prop_Firmware_ProgrammingTarget_String		= 1028,
 	Prop_DeviceClass_Int32						= 1029,
 	Prop_HasCamera_Bool							= 1030,
 	Prop_DriverVersion_String                   = 1031,
 	Prop_Firmware_ForceUpdateRequired_Bool      = 1032,
 	Prop_ViveSystemButtonFixRequired_Bool		= 1033,
 	Prop_ParentDriver_Uint64					= 1034,
 	Prop_ResourceRoot_String					= 1035,
+	Prop_RegisteredDeviceType_String			= 1036,
+	Prop_InputProfilePath_String				= 1037, // input profile to use for this device in the input system. Will default to tracking system name if this isn't provided
+	Prop_NeverTracked_Bool						= 1038, // Used for devices that will never have a valid pose by design
+	Prop_NumCameras_Int32						= 1039,
+	Prop_CameraFrameLayout_Int32				= 1040, // EVRTrackedCameraFrameLayout value
 
 	// Properties that are unique to TrackedDeviceClass_HMD
 	Prop_ReportsTimeSinceVSync_Bool				= 2000,
 	Prop_SecondsFromVsyncToPhotons_Float		= 2001,
 	Prop_DisplayFrequency_Float					= 2002,
 	Prop_UserIpdMeters_Float					= 2003,
 	Prop_CurrentUniverseId_Uint64				= 2004, 
 	Prop_PreviousUniverseId_Uint64				= 2005, 
@@ -311,16 +331,30 @@ enum ETrackedDeviceProperty
 	Prop_DisplayMCImageHeight_Int32				= 2039,
 	Prop_DisplayMCImageNumChannels_Int32		= 2040,
 	Prop_DisplayMCImageData_Binary				= 2041,
 	Prop_SecondsFromPhotonsToVblank_Float		= 2042,
 	Prop_DriverDirectModeSendsVsyncEvents_Bool	= 2043,
 	Prop_DisplayDebugMode_Bool					= 2044,
 	Prop_GraphicsAdapterLuid_Uint64				= 2045,
 	Prop_DriverProvidedChaperonePath_String		= 2048,
+	Prop_ExpectedTrackingReferenceCount_Int32	= 2049, // expected number of sensors or basestations to reserve UI space for
+	Prop_ExpectedControllerCount_Int32			= 2050, // expected number of tracked controllers to reserve UI space for
+	Prop_NamedIconPathControllerLeftDeviceOff_String	= 2051, // placeholder icon for "left" controller if not yet detected/loaded
+	Prop_NamedIconPathControllerRightDeviceOff_String	= 2052, // placeholder icon for "right" controller if not yet detected/loaded
+	Prop_NamedIconPathTrackingReferenceDeviceOff_String	= 2053, // placeholder icon for sensor/base if not yet detected/loaded
+	Prop_DoNotApplyPrediction_Bool				= 2054,
+	Prop_CameraToHeadTransforms_Matrix34_Array	= 2055,
+	Prop_DistortionMeshResolution_Int32			= 2056, // custom resolution of compositor calls to IVRSystem::ComputeDistortion
+	Prop_DriverIsDrawingControllers_Bool		= 2057,
+	Prop_DriverRequestsApplicationPause_Bool	= 2058,
+	Prop_DriverRequestsReducedRendering_Bool	= 2059,
+	Prop_MinimumIpdStepMeters_Float				= 2060,
+	Prop_AudioBridgeFirmwareVersion_Uint64		= 2061,
+	Prop_ImageBridgeFirmwareVersion_Uint64		= 2062,
 
 	// Properties that are unique to TrackedDeviceClass_Controller
 	Prop_AttachedDeviceId_String				= 3000,
 	Prop_SupportedButtons_Uint64				= 3001,
 	Prop_Axis0Type_Int32						= 3002, // Return value is of type EVRControllerAxisType
 	Prop_Axis1Type_Int32						= 3003, // Return value is of type EVRControllerAxisType
 	Prop_Axis2Type_Int32						= 3004, // Return value is of type EVRControllerAxisType
 	Prop_Axis3Type_Int32						= 3005, // Return value is of type EVRControllerAxisType
@@ -345,29 +379,36 @@ enum ETrackedDeviceProperty
 	Prop_NamedIconPathDeviceReadyAlert_String		= 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
 	Prop_NamedIconPathDeviceNotReady_String			= 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
 	Prop_NamedIconPathDeviceStandby_String			= 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
 	Prop_NamedIconPathDeviceAlertLow_String			= 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
 
 	// Properties that are used by helpers, but are opaque to applications
 	Prop_DisplayHiddenArea_Binary_Start				= 5100,
 	Prop_DisplayHiddenArea_Binary_End				= 5150,
+	Prop_ParentContainer							= 5151,
 
 	// Properties that are unique to drivers
 	Prop_UserConfigPath_String					= 6000,
 	Prop_InstallPath_String						= 6001,
 	Prop_HasDisplayComponent_Bool				= 6002,
 	Prop_HasControllerComponent_Bool			= 6003,
 	Prop_HasCameraComponent_Bool				= 6004,
 	Prop_HasDriverDirectModeComponent_Bool		= 6005,
 	Prop_HasVirtualDisplayComponent_Bool		= 6006,
 
+	// Properties that are set internally based on other information provided by drivers
+	Prop_ControllerType_String					= 7000,
+	Prop_LegacyInputProfile_String				= 7001,
+
 	// Vendors are free to expose private debug data in this reserved region
 	Prop_VendorSpecific_Reserved_Start			= 10000,
 	Prop_VendorSpecific_Reserved_End			= 10999,
+	
+	Prop_TrackedDeviceProperty_Max				= 1000000,
 };
 
 /** No string property will ever be longer than this length */
 static const uint32_t k_unMaxPropertyStringSize = 32 * 1024;
 
 /** Used to return errors that occur when reading properties. */
 enum ETrackedPropertyError
 {
@@ -378,26 +419,49 @@ enum ETrackedPropertyError
 	TrackedProp_UnknownProperty				= 4, // Driver has not set the property (and may not ever).
 	TrackedProp_InvalidDevice				= 5,
 	TrackedProp_CouldNotContactServer		= 6,
 	TrackedProp_ValueNotProvidedByDevice	= 7,
 	TrackedProp_StringExceedsMaximumLength	= 8,
 	TrackedProp_NotYetAvailable				= 9, // The property value isn't known yet, but is expected soon. Call again later.
 	TrackedProp_PermissionDenied			= 10,
 	TrackedProp_InvalidOperation			= 11,
+	TrackedProp_CannotWriteToWildcards		= 12,
 };
 
 /** Allows the application to control what part of the provided texture will be used in the
 * frame buffer. */
 struct VRTextureBounds_t
 {
 	float uMin, vMin;
 	float uMax, vMax;
 };
 
+/** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */
+struct VRTextureWithPose_t : public Texture_t
+{
+	HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures.
+};
+
+struct VRTextureDepthInfo_t
+{
+	void* handle; // See ETextureType definition above
+	HmdMatrix44_t mProjection;
+	HmdVector2_t vRange; // 0..1
+};
+
+struct VRTextureWithDepth_t : public Texture_t
+{
+	VRTextureDepthInfo_t depth;
+};
+
+struct VRTextureWithPoseAndDepth_t : public VRTextureWithPose_t
+{
+	VRTextureDepthInfo_t depth;
+};
 
 /** Allows the application to control how scene textures are used by the compositor when calling Submit. */
 enum EVRSubmitFlags
 {
 	// Simple render path. App submits rendered left and right eye images with no lens distortion correction applied.
 	Submit_Default = 0x00,
 
 	// App submits final left and right eye images with lens distortion already applied (lens distortion makes the images appear
@@ -405,16 +469,24 @@ enum EVRSubmitFlags
 	// vr::IVRSystem::ComputeDistortion() to apply the correct distortion to the rendered images before calling Submit().
 	Submit_LensDistortionAlreadyApplied = 0x01,
 
 	// If the texture pointer passed in is actually a renderbuffer (e.g. for MSAA in OpenGL) then set this flag.
 	Submit_GlRenderBuffer = 0x02,
 
 	// Do not use
 	Submit_Reserved = 0x04,
+
+	// Set to indicate that pTexture is a pointer to a VRTextureWithPose_t.
+	// This flag can be combined with Submit_TextureWithDepth to pass a VRTextureWithPoseAndDepth_t.
+	Submit_TextureWithPose = 0x08,
+
+	// Set to indicate that pTexture is a pointer to a VRTextureWithDepth_t.
+	// This flag can be combined with Submit_TextureWithPose to pass a VRTextureWithPoseAndDepth_t.
+	Submit_TextureWithDepth = 0x10,
 };
 
 /** Data required for passing Vulkan textures to IVRCompositor::Submit.
 * Be sure to call OpenVR_Shutdown before destroying these resources. */
 struct VRVulkanTextureData_t
 {
 	uint64_t m_nImage; // VkImage
 	VkDevice_T *m_pDevice;
@@ -468,16 +540,25 @@ enum EVREventType
 	VREvent_WirelessDisconnect			= 112,
 	VREvent_WirelessReconnect			= 113,
 
 	VREvent_ButtonPress					= 200, // data is controller
 	VREvent_ButtonUnpress				= 201, // data is controller
 	VREvent_ButtonTouch					= 202, // data is controller
 	VREvent_ButtonUntouch				= 203, // data is controller
 
+	VREvent_DualAnalog_Press			= 250, // data is dualAnalog
+	VREvent_DualAnalog_Unpress			= 251, // data is dualAnalog
+	VREvent_DualAnalog_Touch			= 252, // data is dualAnalog
+	VREvent_DualAnalog_Untouch			= 253, // data is dualAnalog
+	VREvent_DualAnalog_Move				= 254, // data is dualAnalog
+	VREvent_DualAnalog_ModeSwitch1		= 255, // data is dualAnalog
+	VREvent_DualAnalog_ModeSwitch2		= 256, // data is dualAnalog
+	VREvent_DualAnalog_Cancel			= 257, // data is dualAnalog
+
 	VREvent_MouseMove					= 300, // data is mouse
 	VREvent_MouseButtonDown				= 301, // data is mouse
 	VREvent_MouseButtonUp				= 302, // data is mouse
 	VREvent_FocusEnter					= 303, // data is overlay
 	VREvent_FocusLeave					= 304, // data is overlay
 	VREvent_Scroll						= 305, // data is mouse
 	VREvent_TouchPadMove				= 306, // data is mouse
 	VREvent_OverlayFocusChanged			= 307, // data is overlay, global event
@@ -485,48 +566,56 @@ enum EVREventType
 	VREvent_InputFocusCaptured			= 400, // data is process DEPRECATED
 	VREvent_InputFocusReleased			= 401, // data is process DEPRECATED
 	VREvent_SceneFocusLost				= 402, // data is process
 	VREvent_SceneFocusGained			= 403, // data is process
 	VREvent_SceneApplicationChanged		= 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor)
 	VREvent_SceneFocusChanged			= 405, // data is process - New app got access to draw the scene
 	VREvent_InputFocusChanged			= 406, // data is process
 	VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process
+	VREvent_SceneApplicationUsingWrongGraphicsAdapter = 408, // data is process
+	VREvent_ActionBindingReloaded		 = 409, // data is process - The App that action binds reloaded for
 
 	VREvent_HideRenderModels			= 410, // Sent to the scene application to request hiding render models temporarily
 	VREvent_ShowRenderModels			= 411, // Sent to the scene application to request restoring render model visibility
 
+	VREvent_ConsoleOpened               = 420,
+	VREvent_ConsoleClosed               = 421,
+
 	VREvent_OverlayShown				= 500,
 	VREvent_OverlayHidden				= 501,
 	VREvent_DashboardActivated			= 502,
 	VREvent_DashboardDeactivated		= 503,
 	VREvent_DashboardThumbSelected		= 504, // Sent to the overlay manager - data is overlay
 	VREvent_DashboardRequested			= 505, // Sent to the overlay manager - data is overlay
 	VREvent_ResetDashboard				= 506, // Send to the overlay manager
 	VREvent_RenderToast					= 507, // Send to the dashboard to render a toast - data is the notification ID
 	VREvent_ImageLoaded					= 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading
 	VREvent_ShowKeyboard				= 509, // Sent to keyboard renderer in the dashboard to invoke it
 	VREvent_HideKeyboard				= 510, // Sent to keyboard renderer in the dashboard to hide it
 	VREvent_OverlayGamepadFocusGained	= 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it
 	VREvent_OverlayGamepadFocusLost		= 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else
 	VREvent_OverlaySharedTextureChanged = 513,
-	VREvent_DashboardGuideButtonDown	= 514,
-	VREvent_DashboardGuideButtonUp		= 515,
+	//VREvent_DashboardGuideButtonDown	= 514, // These are no longer sent
+	//VREvent_DashboardGuideButtonUp		= 515,
 	VREvent_ScreenshotTriggered			= 516, // Screenshot button combo was pressed, Dashboard should request a screenshot
 	VREvent_ImageFailed					= 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load
 	VREvent_DashboardOverlayCreated		= 518,
+	VREvent_SwitchGamepadFocus			= 519,
 
 	// Screenshot API
 	VREvent_RequestScreenshot				= 520, // Sent by vrclient application to compositor to take a screenshot
 	VREvent_ScreenshotTaken					= 521, // Sent by compositor to the application that the screenshot has been taken
 	VREvent_ScreenshotFailed				= 522, // Sent by compositor to the application that the screenshot failed to be taken
 	VREvent_SubmitScreenshotToDashboard		= 523, // Sent by compositor to the dashboard that a completed screenshot was submitted
 	VREvent_ScreenshotProgressToDashboard	= 524, // Sent by compositor to the dashboard that a completed screenshot was submitted
 
 	VREvent_PrimaryDashboardDeviceChanged	= 525,
+	VREvent_RoomViewShown					= 526, // Sent by compositor whenever room-view is enabled
+	VREvent_RoomViewHidden					= 527, // Sent by compositor whenever room-view is disabled
 
 	VREvent_Notification_Shown				= 600,
 	VREvent_Notification_Hidden				= 601,
 	VREvent_Notification_BeginInteraction	= 602,
 	VREvent_Notification_Destroyed			= 603,
 
 	VREvent_Quit							= 700, // data is process
 	VREvent_ProcessQuit						= 701, // data is process
@@ -537,26 +626,37 @@ enum EVREventType
 	VREvent_ChaperoneDataHasChanged			= 800,
 	VREvent_ChaperoneUniverseHasChanged		= 801,
 	VREvent_ChaperoneTempDataHasChanged		= 802,
 	VREvent_ChaperoneSettingsHaveChanged	= 803,
 	VREvent_SeatedZeroPoseReset				= 804,
 
 	VREvent_AudioSettingsHaveChanged		= 820,
 
-	VREvent_BackgroundSettingHasChanged		= 850,
-	VREvent_CameraSettingsHaveChanged		= 851,
-	VREvent_ReprojectionSettingHasChanged	= 852,
-	VREvent_ModelSkinSettingsHaveChanged	= 853,
-	VREvent_EnvironmentSettingsHaveChanged	= 854,
-	VREvent_PowerSettingsHaveChanged		= 855,
-	VREvent_EnableHomeAppSettingsHaveChanged = 856,
+	VREvent_BackgroundSettingHasChanged		   = 850,
+	VREvent_CameraSettingsHaveChanged		   = 851,
+	VREvent_ReprojectionSettingHasChanged	   = 852,
+	VREvent_ModelSkinSettingsHaveChanged	   = 853,
+	VREvent_EnvironmentSettingsHaveChanged	   = 854,
+	VREvent_PowerSettingsHaveChanged		   = 855,
+	VREvent_EnableHomeAppSettingsHaveChanged   = 856,
+	VREvent_SteamVRSectionSettingChanged       = 857,
+	VREvent_LighthouseSectionSettingChanged    = 858,
+	VREvent_NullSectionSettingChanged          = 859,
+	VREvent_UserInterfaceSectionSettingChanged = 860,
+	VREvent_NotificationsSectionSettingChanged = 861,
+	VREvent_KeyboardSectionSettingChanged      = 862,
+	VREvent_PerfSectionSettingChanged          = 863,
+	VREvent_DashboardSectionSettingChanged     = 864,
+	VREvent_WebInterfaceSectionSettingChanged  = 865,
 
 	VREvent_StatusUpdate					= 900,
 
+	VREvent_WebInterface_InstallDriverCompleted = 950,
+
 	VREvent_MCImageUpdated					= 1000,
 
 	VREvent_FirmwareUpdateStarted			= 1100,
 	VREvent_FirmwareUpdateFinished			= 1101,
 
 	VREvent_KeyboardClosed					= 1200,
 	VREvent_KeyboardCharInput				= 1201,
 	VREvent_KeyboardDone					= 1202, // Sent when DONE button clicked on keyboard
@@ -581,17 +681,20 @@ enum EVREventType
 	VREvent_TrackedCamera_ResumeVideoStream = 1503,
 	VREvent_TrackedCamera_EditingSurface    = 1550,
 
 	VREvent_PerformanceTest_EnableCapture	= 1600,
 	VREvent_PerformanceTest_DisableCapture	= 1601,
 	VREvent_PerformanceTest_FidelityLevel	= 1602,
 
 	VREvent_MessageOverlay_Closed			= 1650,
+	VREvent_MessageOverlayCloseRequested	= 1651,
 	
+	VREvent_Input_HapticVibration			= 1700, // data is hapticVibration
+
 	// Vendors are free to expose private events in this reserved region
 	VREvent_VendorSpecific_Reserved_Start	= 10000,
 	VREvent_VendorSpecific_Reserved_End		= 19999,
 };
 
 
 /** Level of Hmd activity */
 // UserInteraction_Timeout means the device is in the process of timing out.
@@ -665,17 +768,18 @@ struct VREvent_Mouse_t
 /** used for simulated mouse wheel scroll in overlay space */
 struct VREvent_Scroll_t
 {
 	float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe
 	uint32_t repeatCount;
 };
 
 /** when in mouse input mode you can receive data from the touchpad, these events are only sent if the users finger
-   is on the touchpad (or just released from it) 
+   is on the touchpad (or just released from it). These events are sent to overlays with the VROverlayFlags_SendVRTouchpadEvents
+   flag set.
 **/
 struct VREvent_TouchPadMove_t
 {
 	// true if the users finger is detected on the touch pad
 	bool bFingerDown;
 
 	// How long the finger has been down in seconds
 	float flSecondsFingerDown;
@@ -704,16 +808,17 @@ struct VREvent_Process_t
 	bool bForced;
 };
 
 
 /** Used for a few events about overlays */
 struct VREvent_Overlay_t
 {
 	uint64_t overlayHandle;
+	uint64_t devicePath;
 };
 
 
 /** Used for a few events about overlays */
 struct VREvent_Status_t
 {
 	uint32_t statusState; // EVRState enum
 };
@@ -736,16 +841,18 @@ struct VREvent_Chaperone_t
 	uint64_t m_nCurrentUniverse;
 };
 
 /** Not actually used for any events */
 struct VREvent_Reserved_t
 {
 	uint64_t reserved0;
 	uint64_t reserved1;
+	uint64_t reserved2;
+	uint64_t reserved3;
 };
 
 struct VREvent_PerformanceTest_t
 {
 	uint32_t m_nFidelityLevel;
 };
 
 struct VREvent_SeatedZeroPoseReset_t
@@ -782,16 +889,43 @@ struct VREvent_MessageOverlay_t
 };
 
 struct VREvent_Property_t
 {
 	PropertyContainerHandle_t container;
 	ETrackedDeviceProperty prop;
 };
 
+enum EDualAnalogWhich
+{
+	k_EDualAnalog_Left = 0,
+	k_EDualAnalog_Right = 1,
+};
+
+struct VREvent_DualAnalog_t
+{
+	float x, y; // coordinates are -1..1 analog values
+	float transformedX, transformedY; // transformed by the center and radius numbers provided by the overlay
+	EDualAnalogWhich which;
+};
+
+struct VREvent_HapticVibration_t
+{
+	uint64_t containerHandle; // property container handle of the device with the haptic component
+	uint64_t componentHandle; // Which haptic component needs to vibrate
+	float fDurationSeconds;
+	float fFrequency;
+	float fAmplitude;
+};
+
+struct VREvent_WebConsole_t
+{
+	WebConsoleHandle_t webConsoleHandle;
+};
+
 /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */
 typedef union
 {
 	VREvent_Reserved_t reserved;
 	VREvent_Controller_t controller;
 	VREvent_Mouse_t mouse;
 	VREvent_Scroll_t scroll;
 	VREvent_Process_t process;
@@ -805,16 +939,19 @@ typedef union
 	VREvent_TouchPadMove_t touchPadMove;
 	VREvent_SeatedZeroPoseReset_t seatedZeroPoseReset;
 	VREvent_Screenshot_t screenshot;
 	VREvent_ScreenshotProgress_t screenshotProgress;
 	VREvent_ApplicationLaunch_t applicationLaunch;
 	VREvent_EditingCameraSurface_t cameraSurface;
 	VREvent_MessageOverlay_t messageOverlay;
 	VREvent_Property_t property;
+	VREvent_DualAnalog_t dualAnalog;
+	VREvent_HapticVibration_t hapticVibration;
+	VREvent_WebConsole_t webConsole;
 } VREvent_Data_t;
 
 
 #if defined(__linux__) || defined(__APPLE__) 
 // This structure was originally defined mis-packed on Linux, preserved for 
 // compatibility. 
 #pragma pack( push, 4 )
 #endif
@@ -828,16 +965,31 @@ struct VREvent_t
 	// event data must be the end of the struct as its size is variable
 	VREvent_Data_t data;
 };
 
 #if defined(__linux__) || defined(__APPLE__) 
 #pragma pack( pop )
 #endif
 
+enum EVRInputError
+{
+	VRInputError_None = 0,
+	VRInputError_NameNotFound = 1,
+	VRInputError_WrongType = 2,
+	VRInputError_InvalidHandle = 3,
+	VRInputError_InvalidParam = 4,
+	VRInputError_NoSteam = 5,
+	VRInputError_MaxCapacityReached = 6,
+	VRInputError_IPCError = 7,
+	VRInputError_NoActiveActionSet = 8,
+	VRInputError_InvalidDevice = 9,
+};
+
+
 /** The mesh to draw into the stencil (or depth) buffer to perform 
 * early stencil (or depth) kills of pixels that will never appear on the HMD.
 * This mesh draws on all the pixels that will be hidden after distortion. 
 *
 * If the HMD does not provide a visible area mesh pVertexData will be
 * NULL and unTriangleCount will be 0. */
 struct HiddenAreaMesh_t
 {
@@ -965,16 +1117,19 @@ enum EVROverlayError
 	VROverlayError_ArrayTooSmall			= 22,
 	VROverlayError_RequestFailed			= 23,
 	VROverlayError_InvalidTexture			= 24,
 	VROverlayError_UnableToLoadFile			= 25,
 	VROverlayError_KeyboardAlreadyInUse		= 26,
 	VROverlayError_NoNeighbor				= 27,
 	VROverlayError_TooManyMaskPrimitives	= 29,
 	VROverlayError_BadMaskPrimitive			= 30,
+	VROverlayError_TextureAlreadyLocked		= 31,
+	VROverlayError_TextureLockCapacityReached = 32,
+	VROverlayError_TextureNotLocked			= 33,
 };
 
 /** enum values to pass in to VR_Init to identify whether the application will 
 * draw a 3D scene. */
 enum EVRApplicationType
 {
 	VRApplication_Other = 0,		// Some other kind of application that isn't covered by the other entries 
 	VRApplication_Scene	= 1,		// Application will submit 3D frames 
@@ -1014,86 +1169,92 @@ enum EVRNotificationError
 /** error codes returned by Vr_Init */
 
 // Please add adequate error description to https://developer.valvesoftware.com/w/index.php?title=Category:SteamVRHelp
 enum EVRInitError
 {
 	VRInitError_None	= 0,
 	VRInitError_Unknown = 1,
 
-	VRInitError_Init_InstallationNotFound		= 100,
-	VRInitError_Init_InstallationCorrupt		= 101,
-	VRInitError_Init_VRClientDLLNotFound		= 102,
-	VRInitError_Init_FileNotFound				= 103,
-	VRInitError_Init_FactoryNotFound			= 104,
-	VRInitError_Init_InterfaceNotFound			= 105,
-	VRInitError_Init_InvalidInterface			= 106,
-	VRInitError_Init_UserConfigDirectoryInvalid = 107,
-	VRInitError_Init_HmdNotFound				= 108,
-	VRInitError_Init_NotInitialized				= 109,
-	VRInitError_Init_PathRegistryNotFound		= 110,
-	VRInitError_Init_NoConfigPath				= 111,
-	VRInitError_Init_NoLogPath					= 112,
-	VRInitError_Init_PathRegistryNotWritable	= 113,
-	VRInitError_Init_AppInfoInitFailed			= 114,
-	VRInitError_Init_Retry						= 115, // Used internally to cause retries to vrserver
-	VRInitError_Init_InitCanceledByUser			= 116, // The calling application should silently exit. The user canceled app startup
-	VRInitError_Init_AnotherAppLaunching		= 117, 
-	VRInitError_Init_SettingsInitFailed			= 118, 
-	VRInitError_Init_ShuttingDown				= 119,
-	VRInitError_Init_TooManyObjects				= 120,
-	VRInitError_Init_NoServerForBackgroundApp	= 121,
-	VRInitError_Init_NotSupportedWithCompositor	= 122,
-	VRInitError_Init_NotAvailableToUtilityApps	= 123,
-	VRInitError_Init_Internal				 	= 124,
-	VRInitError_Init_HmdDriverIdIsNone		 	= 125,
-	VRInitError_Init_HmdNotFoundPresenceFailed 	= 126,
-	VRInitError_Init_VRMonitorNotFound			= 127,
-	VRInitError_Init_VRMonitorStartupFailed		= 128,
-	VRInitError_Init_LowPowerWatchdogNotSupported = 129, 
-	VRInitError_Init_InvalidApplicationType		= 130,
-	VRInitError_Init_NotAvailableToWatchdogApps = 131,
-	VRInitError_Init_WatchdogDisabledInSettings = 132,
-	VRInitError_Init_VRDashboardNotFound		= 133,
-	VRInitError_Init_VRDashboardStartupFailed	= 134,
-	VRInitError_Init_VRHomeNotFound				= 135,
-	VRInitError_Init_VRHomeStartupFailed		= 136,
-
-	VRInitError_Driver_Failed				= 200,
-	VRInitError_Driver_Unknown				= 201,
-	VRInitError_Driver_HmdUnknown			= 202,
-	VRInitError_Driver_NotLoaded			= 203,
-	VRInitError_Driver_RuntimeOutOfDate		= 204,
-	VRInitError_Driver_HmdInUse				= 205,
-	VRInitError_Driver_NotCalibrated		= 206,
-	VRInitError_Driver_CalibrationInvalid	= 207,
-	VRInitError_Driver_HmdDisplayNotFound	= 208,
+	VRInitError_Init_InstallationNotFound			= 100,
+	VRInitError_Init_InstallationCorrupt			= 101,
+	VRInitError_Init_VRClientDLLNotFound			= 102,
+	VRInitError_Init_FileNotFound					= 103,
+	VRInitError_Init_FactoryNotFound				= 104,
+	VRInitError_Init_InterfaceNotFound				= 105,
+	VRInitError_Init_InvalidInterface				= 106,
+	VRInitError_Init_UserConfigDirectoryInvalid		= 107,
+	VRInitError_Init_HmdNotFound					= 108,
+	VRInitError_Init_NotInitialized					= 109,
+	VRInitError_Init_PathRegistryNotFound			= 110,
+	VRInitError_Init_NoConfigPath					= 111,
+	VRInitError_Init_NoLogPath						= 112,
+	VRInitError_Init_PathRegistryNotWritable		= 113,
+	VRInitError_Init_AppInfoInitFailed				= 114,
+	VRInitError_Init_Retry							= 115, // Used internally to cause retries to vrserver
+	VRInitError_Init_InitCanceledByUser				= 116, // The calling application should silently exit. The user canceled app startup
+	VRInitError_Init_AnotherAppLaunching			= 117, 
+	VRInitError_Init_SettingsInitFailed				= 118, 
+	VRInitError_Init_ShuttingDown					= 119,
+	VRInitError_Init_TooManyObjects					= 120,
+	VRInitError_Init_NoServerForBackgroundApp		= 121,
+	VRInitError_Init_NotSupportedWithCompositor		= 122,
+	VRInitError_Init_NotAvailableToUtilityApps		= 123,
+	VRInitError_Init_Internal				 		= 124,
+	VRInitError_Init_HmdDriverIdIsNone		 		= 125,
+	VRInitError_Init_HmdNotFoundPresenceFailed 		= 126,
+	VRInitError_Init_VRMonitorNotFound				= 127,
+	VRInitError_Init_VRMonitorStartupFailed			= 128,
+	VRInitError_Init_LowPowerWatchdogNotSupported	= 129, 
+	VRInitError_Init_InvalidApplicationType			= 130,
+	VRInitError_Init_NotAvailableToWatchdogApps		= 131,
+	VRInitError_Init_WatchdogDisabledInSettings		= 132,
+	VRInitError_Init_VRDashboardNotFound			= 133,
+	VRInitError_Init_VRDashboardStartupFailed		= 134,
+	VRInitError_Init_VRHomeNotFound					= 135,
+	VRInitError_Init_VRHomeStartupFailed			= 136,
+	VRInitError_Init_RebootingBusy					= 137,
+	VRInitError_Init_FirmwareUpdateBusy				= 138,
+	VRInitError_Init_FirmwareRecoveryBusy			= 139,
+	VRInitError_Init_USBServiceBusy					= 140,
+	VRInitError_Init_VRWebHelperStartupFailed		= 141,
+
+	VRInitError_Driver_Failed						= 200,
+	VRInitError_Driver_Unknown						= 201,
+	VRInitError_Driver_HmdUnknown					= 202,
+	VRInitError_Driver_NotLoaded					= 203,
+	VRInitError_Driver_RuntimeOutOfDate				= 204,
+	VRInitError_Driver_HmdInUse						= 205,
+	VRInitError_Driver_NotCalibrated				= 206,
+	VRInitError_Driver_CalibrationInvalid			= 207,
+	VRInitError_Driver_HmdDisplayNotFound			= 208,
 	VRInitError_Driver_TrackedDeviceInterfaceUnknown = 209,
-	// VRInitError_Driver_HmdDisplayNotFoundAfterFix	 = 210, // not needed: here for historic reasons
-	VRInitError_Driver_HmdDriverIdOutOfBounds = 211,
-	VRInitError_Driver_HmdDisplayMirrored  = 212,
-
-	VRInitError_IPC_ServerInitFailed		= 300,
-	VRInitError_IPC_ConnectFailed			= 301,
-	VRInitError_IPC_SharedStateInitFailed	= 302,
-	VRInitError_IPC_CompositorInitFailed	= 303,
-	VRInitError_IPC_MutexInitFailed			= 304,
-	VRInitError_IPC_Failed					= 305,
-	VRInitError_IPC_CompositorConnectFailed	= 306,
+	// VRInitError_Driver_HmdDisplayNotFoundAfterFix = 210, // not needed: here for historic reasons
+	VRInitError_Driver_HmdDriverIdOutOfBounds		= 211,
+	VRInitError_Driver_HmdDisplayMirrored			= 212,
+
+	VRInitError_IPC_ServerInitFailed				= 300,
+	VRInitError_IPC_ConnectFailed					= 301,
+	VRInitError_IPC_SharedStateInitFailed			= 302,
+	VRInitError_IPC_CompositorInitFailed			= 303,
+	VRInitError_IPC_MutexInitFailed					= 304,
+	VRInitError_IPC_Failed							= 305,
+	VRInitError_IPC_CompositorConnectFailed			= 306,
 	VRInitError_IPC_CompositorInvalidConnectResponse = 307,
 	VRInitError_IPC_ConnectFailedAfterMultipleAttempts = 308,
 
 	VRInitError_Compositor_Failed					= 400,
 	VRInitError_Compositor_D3D11HardwareRequired	= 401,
 	VRInitError_Compositor_FirmwareRequiresUpdate	= 402,
 	VRInitError_Compositor_OverlayInitFailed		= 403,
 	VRInitError_Compositor_ScreenshotsInitFailed	= 404,
 	VRInitError_Compositor_UnableToCreateDevice		= 405,
 
-	VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000,
+	VRInitError_VendorSpecific_UnableToConnectToOculusRuntime		= 1000,
+	VRInitError_VendorSpecific_WindowsNotInDevMode					= 1001,
 
 	VRInitError_VendorSpecific_HmdFound_CantOpenDevice 				= 1101,
 	VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart	= 1102,
 	VRInitError_VendorSpecific_HmdFound_NoStoredConfig 				= 1103,
 	VRInitError_VendorSpecific_HmdFound_ConfigTooBig 				= 1104,
 	VRInitError_VendorSpecific_HmdFound_ConfigTooSmall 				= 1105,
 	VRInitError_VendorSpecific_HmdFound_UnableToInitZLib 			= 1106,
 	VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion 	= 1107,
@@ -1139,16 +1300,24 @@ enum EVRTrackedCameraError
 	VRTrackedCameraError_InvalidSharedTextureHandle = 110,
 	VRTrackedCameraError_FailedToGetGLTextureId     = 111,
 	VRTrackedCameraError_SharedTextureFailure       = 112,
 	VRTrackedCameraError_NoFrameAvailable           = 113,
 	VRTrackedCameraError_InvalidArgument            = 114,
 	VRTrackedCameraError_InvalidFrameBufferSize     = 115,
 };
 
+enum EVRTrackedCameraFrameLayout
+{
+	EVRTrackedCameraFrameLayout_Mono				= 0x0001,
+	EVRTrackedCameraFrameLayout_Stereo				= 0x0002,
+	EVRTrackedCameraFrameLayout_VerticalLayout		= 0x0010,	// Stereo frames are Top/Bottom (left/right)
+	EVRTrackedCameraFrameLayout_HorizontalLayout	= 0x0020,	// Stereo frames are Left/Right
+};
+	
 enum EVRTrackedCameraFrameType
 {
 	VRTrackedCameraFrameType_Distorted = 0,			// This is the camera video frame size in pixels, still distorted.
 	VRTrackedCameraFrameType_Undistorted,			// In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly.
 	VRTrackedCameraFrameType_MaximumUndistorted,	// In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions.
 	MAX_CAMERA_FRAME_TYPES
 };
 
@@ -1168,27 +1337,40 @@ struct CameraVideoStreamFrameHeader_t
 	TrackedDevicePose_t standingTrackedDevicePose;
 };
 
 // Screenshot types
 typedef uint32_t ScreenshotHandle_t;
 
 static const uint32_t k_unScreenshotHandleInvalid = 0;
 
+/** Frame timing data provided by direct mode drivers. */
+struct DriverDirectMode_FrameTiming
+{
+	uint32_t m_nSize; // Set to sizeof( DriverDirectMode_FrameTiming )
+	uint32_t m_nNumFramePresents; // number of times frame was presented
+	uint32_t m_nNumMisPresented; // number of times frame was presented on a vsync other than it was originally predicted to
+	uint32_t m_nNumDroppedFrames; // number of additional times previous frame was scanned out (i.e. compositor missed vsync)
+	uint32_t m_nReprojectionFlags;
+};
+
+enum EVSync
+{
+	VSync_None,
+	VSync_WaitRender,	// block following render work until vsync
+	VSync_NoWaitRender,	// do not block following render work (allow to get started early)
+};
+
 #pragma pack( pop )
 
-
-// Mozilla changed VR_INTERFACE.  We don't want to extern the API functions.
-// See README.mozilla
-#define VR_INTERFACE
+#define VR_INTERFACE 
 
 /*
 // figure out how to import from the VR API dll
 #if defined(_WIN32)
-
 #ifdef VR_API_EXPORT
 #define VR_INTERFACE extern "C" __declspec( dllexport )
 #else
 #define VR_INTERFACE extern "C" __declspec( dllimport )
 #endif
 
 #elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__)
 
@@ -1198,16 +1380,17 @@ static const uint32_t k_unScreenshotHand
 #define VR_INTERFACE extern "C" 
 #endif
 
 #else
 #error "Unsupported Platform."
 #endif
 */
 
+
 #if defined( _WIN32 )
 #define VR_CALLTYPE __cdecl
 #else
 #define VR_CALLTYPE 
 #endif
 
 } // namespace vr
 
@@ -1284,27 +1467,35 @@ public:
 	* and swap chain in DX10 and DX11. If an error occurs the index will be set to -1.
 	*/
 	virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex ) = 0;
 	
 	/**
 	 * Returns platform- and texture-type specific adapter identification so that applications and the
 	 * compositor are creating textures and swap chains on the same GPU. If an error occurs the device
 	 * will be set to 0.
+	 * pInstance is an optional parameter that is required only when textureType is TextureType_Vulkan.
 	 * [D3D10/11/12 Only (D3D9 Not Supported)]
 	 *  Returns the adapter LUID that identifies the GPU attached to the HMD. The user should
 	 *  enumerate all adapters using IDXGIFactory::EnumAdapters and IDXGIAdapter::GetDesc to find
 	 *  the adapter with the matching LUID, or use IDXGIFactory4::EnumAdapterByLuid.
 	 *  The discovered IDXGIAdapter should be used to create the device and swap chain.
 	 * [Vulkan Only]
-	 *  Returns the vk::PhysicalDevice that should be used by the application.
+	 *  Returns the VkPhysicalDevice that should be used by the application.
+	 *  pInstance must be the instance the application will use to query for the VkPhysicalDevice.  The application
+	 *  must create the VkInstance with extensions returned by IVRCompositor::GetVulkanInstanceExtensionsRequired enabled.
 	 * [macOS Only]
-	 *  Returns an id<MTLDevice> that should be used by the application.
+	 *  For TextureType_IOSurface returns the id<MTLDevice> that should be used by the application.
+	 *  On 10.13+ for TextureType_OpenGL returns the 'registryId' of the renderer which should be used
+	 *   by the application. See Apple Technical Q&A QA1168 for information on enumerating GL Renderers, and the
+	 *   new kCGLRPRegistryIDLow and kCGLRPRegistryIDHigh CGLRendererProperty values in the 10.13 SDK.
+	 *  Pre 10.13 for TextureType_OpenGL returns 0, as there is no dependable way to correlate the HMDs MTLDevice
+	 *   with a GL Renderer.
 	 */
-	virtual void GetOutputDevice( uint64_t *pnDevice, ETextureType textureType ) = 0;
+	virtual void GetOutputDevice( uint64_t *pnDevice, ETextureType textureType, VkInstance_T *pInstance = nullptr ) = 0;
 
 	// ------------------------------------
 	// Display Mode methods
 	// ------------------------------------
 
 	/** Use to determine if the headset display is part of the desktop (i.e. extended) or hidden (i.e. direct mode). */
 	virtual bool IsDisplayOnDesktop() = 0;
 
@@ -1401,16 +1592,21 @@ public:
 	/** Returns an int property. If the device index is not valid or the property is not a int type this function will return 0. */
 	virtual int32_t GetInt32TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0;
 
 	/** Returns a uint64 property. If the device index is not valid or the property is not a uint64 type this function will return 0. */
 	virtual uint64_t GetUint64TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0;
 
 	/** Returns a matrix property. If the device index is not valid or the property is not a matrix type, this function will return identity. */
 	virtual HmdMatrix34_t GetMatrix34TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0;
+	
+	/** Returns an array of one type of property. If the device index is not valid or the property is not a single value or an array of the specified type,
+	* this function will return 0. Otherwise it returns the number of bytes necessary to hold the array of properties. If unBufferSize is
+	* greater than the returned size and pBuffer is non-NULL, pBuffer is filled with the contents of array of properties. */
+	virtual uint32_t GetArrayTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, PropertyTypeTag_t propType, void *pBuffer, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ) = 0;
 
 	/** Returns a string property. If the device index is not valid or the property is not a string type this function will 
 	* return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing
 	* null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */
 	virtual uint32_t GetStringTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ) = 0;
 
 	/** returns a string that corresponds with the specified property error. The string will be the name 
 	* of the error enum value for all valid error codes */
@@ -1465,36 +1661,40 @@ public:
 	virtual void TriggerHapticPulse( vr::TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec ) = 0;
 
 	/** returns the name of an EVRButtonId enum value */
 	virtual const char *GetButtonIdNameFromEnum( EVRButtonId eButtonId ) = 0;
 
 	/** returns the name of an EVRControllerAxisType enum value */
 	virtual const char *GetControllerAxisTypeNameFromEnum( EVRControllerAxisType eAxisType ) = 0;
 
-	/** Tells OpenVR that this process wants exclusive access to controller button states and button events. Other apps will be notified that 
-	* they have lost input focus with a VREvent_InputFocusCaptured event. Returns false if input focus could not be captured for
-	* some reason. */
-	virtual bool CaptureInputFocus() = 0;
-
-	/** Tells OpenVR that this process no longer wants exclusive access to button states and button events. Other apps will be notified 
-	* that input focus has been released with a VREvent_InputFocusReleased event. */
-	virtual void ReleaseInputFocus() = 0;
-
-	/** Returns true if input focus is captured by another process. */
-	virtual bool IsInputFocusCapturedByAnotherProcess() = 0;
+	/** Returns true if this application is receiving input from the system. This would return false if 
+	* system-related functionality is consuming the input stream. */
+	virtual bool IsInputAvailable() = 0;
+
+	/** Returns true SteamVR is drawing controllers on top of the application. Applications should consider
+	* not drawing anything attached to the user's hands in this case. */
+	virtual bool IsSteamVRDrawingControllers() = 0;
+
+	/** Returns true if the user has put SteamVR into a mode that is distracting them from the application.
+	* For applications where this is appropriate, the application should pause ongoing activity. */
+	virtual bool ShouldApplicationPause() = 0;
+
+	/** Returns true if SteamVR is doing significant rendering work and the game should do what it can to reduce
+	* its own workload. One common way to do this is to reduce the size of the render target provided for each eye. */
+	virtual bool ShouldApplicationReduceRenderingWork() = 0;
 
 	// ------------------------------------
 	// Debug Methods
 	// ------------------------------------
 
 	/** Sends a request to the driver for the specified device and returns the response. The maximum response size is 32k,
 	* but this method can be called with a smaller buffer. If the response exceeds the size of the buffer, it is truncated. 
 	* The size of the response including its terminating null is returned. */
-	virtual uint32_t DriverDebugRequest( vr::TrackedDeviceIndex_t unDeviceIndex, const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize ) = 0;
+	virtual uint32_t DriverDebugRequest( vr::TrackedDeviceIndex_t unDeviceIndex, const char *pchRequest, VR_OUT_STRING() char *pchResponseBuffer, uint32_t unResponseBufferSize ) = 0;
 
 	// ------------------------------------
 	// Firmware methods
 	// ------------------------------------
 	
 	/** Performs the actual firmware update if applicable. 
 	 * The following events will be sent, if VRFirmwareError_None was returned: VREvent_FirmwareUpdateStarted, VREvent_FirmwareUpdateFinished 
 	 * Use the properties Prop_Firmware_UpdateAvailable_Bool, Prop_Firmware_ManualUpdate_Bool, and Prop_Firmware_ManualUpdateURL_String
@@ -1512,17 +1712,17 @@ public:
 
 	/** Call this to tell the system that the user is being prompted to save data. This
 	* halts the timeout and dismisses the dashboard (if it was up). Applications should be sure to actually 
 	* prompt the user to save and then exit afterward, otherwise the user will be left in a confusing state. */
 	virtual void AcknowledgeQuit_UserPrompt() = 0;
 
 };
 
-static const char * const IVRSystem_Version = "IVRSystem_016";
+static const char * const IVRSystem_Version = "IVRSystem_019";
 
 }
 
 
 // ivrapplications.h
 namespace vr
 {
 
@@ -1567,16 +1767,17 @@ namespace vr
 		VRApplicationProperty_BinaryPath_String			= 13,
 		VRApplicationProperty_Arguments_String			= 14,
 		VRApplicationProperty_URL_String				= 15,
 
 		VRApplicationProperty_Description_String		= 50,
 		VRApplicationProperty_NewsURL_String			= 51,
 		VRApplicationProperty_ImagePath_String			= 52,
 		VRApplicationProperty_Source_String				= 53,
+		VRApplicationProperty_ActionManifestURL_String	= 54,
 
 		VRApplicationProperty_IsDashboardOverlay_Bool	= 60,
 		VRApplicationProperty_IsTemplate_Bool			= 61,
 		VRApplicationProperty_IsInstanced_Bool			= 62,
 		VRApplicationProperty_IsInternal_Bool			= 63,
 		VRApplicationProperty_WantsCompositorPauseInStandby_Bool = 64,
 
 		VRApplicationProperty_LastLaunchTime_Uint64		= 70,
@@ -1624,17 +1825,17 @@ namespace vr
 
 		/** Returns the key of the specified application. The index is at least 0 and is less than the return 
 		* value of GetApplicationCount(). The buffer should be at least k_unMaxApplicationKeyLength in order to 
 		* fit the key. */
 		virtual EVRApplicationError GetApplicationKeyByIndex( uint32_t unApplicationIndex, VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0;
 
 		/** Returns the key of the application for the specified Process Id. The buffer should be at least 
 		* k_unMaxApplicationKeyLength in order to fit the key. */
-		virtual EVRApplicationError GetApplicationKeyByProcessId( uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0;
+		virtual EVRApplicationError GetApplicationKeyByProcessId( uint32_t unProcessId, VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0;
 
 		/** Launches the application. The existing scene application will exit and then the new application will start.
 		* This call is not valid for dashboard overlay applications. */
 		virtual EVRApplicationError LaunchApplication( const char *pchAppKey ) = 0;
 
 		/** Launches an instance of an application of type template, with its app key being pchNewAppKey (which must be unique) and optionally override sections
 		* from the manifest file via AppOverrideKeys_t
 		*/
@@ -1678,31 +1879,31 @@ namespace vr
 
 		/** Gets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */
 		virtual bool GetApplicationAutoLaunch( const char *pchAppKey ) = 0;
 
 		/** Adds this mime-type to the list of supported mime types for this application*/
 		virtual EVRApplicationError SetDefaultApplicationForMimeType( const char *pchAppKey, const char *pchMimeType ) = 0;
 
 		/** return the app key that will open this mime type */
-		virtual bool GetDefaultApplicationForMimeType( const char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0;
+		virtual bool GetDefaultApplicationForMimeType( const char *pchMimeType, VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0;
 
 		/** Get the list of supported mime types for this application, comma-delimited */
-		virtual bool GetApplicationSupportedMimeTypes( const char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer ) = 0;
+		virtual bool GetApplicationSupportedMimeTypes( const char *pchAppKey, VR_OUT_STRING() char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer ) = 0;
 
 		/** Get the list of app-keys that support this mime type, comma-delimited, the return value is number of bytes you need to return the full string */
-		virtual uint32_t GetApplicationsThatSupportMimeType( const char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer ) = 0;
+		virtual uint32_t GetApplicationsThatSupportMimeType( const char *pchMimeType, VR_OUT_STRING() char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer ) = 0;
 
 		/** Get the args list from an app launch that had the process already running, you call this when you get a VREvent_ApplicationMimeTypeLoad */
-		virtual uint32_t GetApplicationLaunchArguments( uint32_t unHandle, char *pchArgs, uint32_t unArgs ) = 0;
+		virtual uint32_t GetApplicationLaunchArguments( uint32_t unHandle, VR_OUT_STRING() char *pchArgs, uint32_t unArgs ) = 0;
 
 		// ---------------  Transition methods --------------- //
 
 		/** Returns the app key for the application that is starting up */
-		virtual EVRApplicationError GetStartingApplication( char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0;
+		virtual EVRApplicationError GetStartingApplication( VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0;
 
 		/** Returns the application transition state */
 		virtual EVRApplicationTransitionState GetTransitionState() = 0;
 
 		/** Returns errors that would prevent the specified application from launching immediately. Calling this function will
 		* cause the current scene application to quit, so only call it when you are actually about to launch something else.
 		* What the caller should do about these failures depends on the failure:
 		*   VRApplicationError_OldApplicationQuitting - An existing application has been told to quit. Wait for a VREvent_ProcessQuit
@@ -1819,25 +2020,35 @@ namespace vr
 	static const char * const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch";
 	static const char * const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch";
 	static const char * const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard";
 	static const char * const k_pch_SteamVR_EnableHomeApp = "enableHomeApp";
 	static const char * const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec";
 	static const char * const k_pch_SteamVR_RetailDemo_Bool = "retailDemo";
 	static const char * const k_pch_SteamVR_IpdOffset_Float = "ipdOffset";
 	static const char * const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering";
+	static const char * const k_pch_SteamVR_SupersampleManualOverride_Bool = "supersampleManualOverride";
+	static const char * const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync";
+	static const char * const k_pch_SteamVR_AllowDisplayLockedMode_Bool = "allowDisplayLockedMode";
+	static const char * const k_pch_SteamVR_HaveStartedTutorialForNativeChaperoneDriver_Bool = "haveStartedTutorialForNativeChaperoneDriver";
+	static const char * const k_pch_SteamVR_ForceWindows32bitVRMonitor = "forceWindows32BitVRMonitor";
+	static const char * const k_pch_SteamVR_DebugInput = "debugInput";
+	static const char * const k_pch_SteamVR_LegacyInputRebinding = "legacyInputRebinding";
 
 	//-----------------------------------------------------------------------------
 	// lighthouse keys
 	static const char * const k_pch_Lighthouse_Section = "driver_lighthouse";
 	static const char * const k_pch_Lighthouse_DisableIMU_Bool = "disableimu";
+	static const char * const k_pch_Lighthouse_DisableIMUExceptHMD_Bool = "disableimuexcepthmd";
 	static const char * const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation";
 	static const char * const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug";
 	static const char * const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation";
 	static const char * const k_pch_Lighthouse_DBHistory_Bool = "dbhistory";
+	static const char * const k_pch_Lighthouse_EnableBluetooth_Bool = "enableBluetooth";
+	static const char * const k_pch_Lighthouse_PowerManagedBaseStations_String = "PowerManagedBaseStations";
 
 	//-----------------------------------------------------------------------------
 	// null keys
 	static const char * const k_pch_Null_Section = "driver_null";
 	static const char * const k_pch_Null_SerialNumber_String = "serialNumber";
 	static const char * const k_pch_Null_ModelNumber_String = "modelNumber";
 	static const char * const k_pch_Null_WindowX_Int32 = "windowX";
 	static const char * const k_pch_Null_WindowY_Int32 = "windowY";
@@ -1903,16 +2114,17 @@ namespace vr
 	static const char * const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard";
 	static const char * const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds";
 	static const char * const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView";
 	static const char * const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR";
 	static const char * const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG";
 	static const char * const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB";
 	static const char * const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA";
 	static const char * const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength";
+	static const char * const k_pch_Camera_RoomViewMode_Int32 = "cameraRoomViewMode";
 
 	//-----------------------------------------------------------------------------
 	// audio keys
 	static const char * const k_pch_audio_Section = "audio";
 	static const char * const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice";
 	static const char * const k_pch_audio_OnRecordDevice_String = "onRecordDevice";
 	static const char * const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice";
 	static const char * const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice";
@@ -1929,25 +2141,32 @@ namespace vr
 	static const char * const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress";
 	static const char * const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby";
 
 	//-----------------------------------------------------------------------------
 	// dashboard keys
 	static const char * const k_pch_Dashboard_Section = "dashboard";
 	static const char * const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard";
 	static const char * const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode";
+	static const char * const k_pch_Dashboard_EnableWebUI = "webUI";
+	static const char * const k_pch_Dashboard_EnableWebUIDevTools = "webUIDevTools";
 
 	//-----------------------------------------------------------------------------
 	// model skin keys
 	static const char * const k_pch_modelskin_Section = "modelskins";
 
 	//-----------------------------------------------------------------------------
 	// driver keys - These could be checked in any driver_<name> section
 	static const char * const k_pch_Driver_Enable_Bool = "enable";
 
+	//-----------------------------------------------------------------------------
+	// web interface keys
+	static const char* const k_pch_WebInterface_Section = "WebInterface";
+	static const char* const k_pch_WebInterface_WebPort_String = "WebPort";
+
 } // namespace vr
 
 // ivrchaperone.h
 namespace vr
 {
 
 #pragma pack( push, 8 )
 
@@ -2124,16 +2343,24 @@ enum EVRCompositorError
 	VRCompositorError_TextureIsOnWrongDevice	= 104,
 	VRCompositorError_TextureUsesUnsupportedFormat = 105,
 	VRCompositorError_SharedTexturesNotSupported = 106,
 	VRCompositorError_IndexOutOfRange			= 107,
 	VRCompositorError_AlreadySubmitted			= 108,
 	VRCompositorError_InvalidBounds				= 109,
 };
 
+/** Timing mode passed to SetExplicitTimingMode(); see that function for documentation */
+enum EVRCompositorTimingMode
+{
+	VRCompositorTimingMode_Implicit											= 0,
+	VRCompositorTimingMode_Explicit_RuntimePerformsPostPresentHandoff		= 1,
+	VRCompositorTimingMode_Explicit_ApplicationPerformsPostPresentHandoff	= 2,
+};
+
 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,
 															// 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.
@@ -2370,19 +2597,46 @@ public:
 	* null.  The string will be a space separated list of-required instance extensions to enable in VkCreateInstance */
 	virtual uint32_t GetVulkanInstanceExtensionsRequired( VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0;
 
 	/** [Vulkan only]
 	* return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing
 	* null.  The string will be a space separated list of required device extensions to enable in VkCreateDevice */
 	virtual uint32_t GetVulkanDeviceExtensionsRequired( VkPhysicalDevice_T *pPhysicalDevice, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0;
 
+	/** [ Vulkan/D3D12 Only ]
+	* There are two purposes for SetExplicitTimingMode:
+	*	1. To get a more accurate GPU timestamp for when the frame begins in Vulkan/D3D12 applications.
+	*	2. (Optional) To avoid having WaitGetPoses access the Vulkan queue so that the queue can be accessed from
+	*	another thread while WaitGetPoses is executing.
+	*
+	* More accurate GPU timestamp for the start of the frame is achieved by the application calling
+	* SubmitExplicitTimingData immediately before its first submission to the Vulkan/D3D12 queue.
+	* This is more accurate because normally this GPU timestamp is recorded during WaitGetPoses.  In D3D11, 
+	* WaitGetPoses queues a GPU timestamp write, but it does not actually get submitted to the GPU until the 
+	* application flushes.  By using SubmitExplicitTimingData, the timestamp is recorded at the same place for 
+	* Vulkan/D3D12 as it is for D3D11, resulting in a more accurate GPU time measurement for the frame.
+	*
+	* Avoiding WaitGetPoses accessing the Vulkan queue can be achieved using SetExplicitTimingMode as well.  If this is desired,
+	* the application should set the timing mode to Explicit_ApplicationPerformsPostPresentHandoff and *MUST* call PostPresentHandoff
+	* itself. If these conditions are met, then WaitGetPoses is guaranteed not to access the queue.  Note that PostPresentHandoff
+	* and SubmitExplicitTimingData will access the queue, so only WaitGetPoses becomes safe for accessing the queue from another
+	* thread. */
+	virtual void SetExplicitTimingMode( EVRCompositorTimingMode eTimingMode ) = 0;
+
+	/** [ Vulkan/D3D12 Only ]
+	* Submit explicit timing data.  When SetExplicitTimingMode is true, this must be called immediately before
+	* the application's first vkQueueSubmit (Vulkan) or ID3D12CommandQueue::ExecuteCommandLists (D3D12) of each frame.
+	* This function will insert a GPU timestamp write just before the application starts its rendering.  This function
+	* will perform a vkQueueSubmit on Vulkan so must not be done simultaneously with VkQueue operations on another thread.
+	* Returns VRCompositorError_RequestFailed if SetExplicitTimingMode is not enabled. */
+	virtual EVRCompositorError SubmitExplicitTimingData() = 0;
 };
 
-static const char * const IVRCompositor_Version = "IVRCompositor_020";
+static const char * const IVRCompositor_Version = "IVRCompositor_022";
 
 } // namespace vr
 
 
 
 // ivrnotifications.h
 namespace vr
 {
@@ -2488,16 +2742,17 @@ namespace vr
 	/** The maximum number of overlay intersection mask primitives per overlay */
 	static const uint32_t k_unMaxOverlayIntersectionMaskPrimitivesCount = 32;
 
 	/** Types of input supported by VR Overlays */
 	enum VROverlayInputMethod
 	{
 		VROverlayInputMethod_None		= 0, // No input events will be generated automatically for this overlay
 		VROverlayInputMethod_Mouse		= 1, // Tracked controllers will get mouse events automatically
+		VROverlayInputMethod_DualAnalog = 2, // Analog inputs from tracked controllers are turned into DualAnalog events
 	};
 
 	/** Allows the caller to figure out which overlay transform getter to call. */
 	enum VROverlayTransformType
 	{
 		VROverlayTransform_Absolute					= 0,
 		VROverlayTransform_TrackedDeviceRelative	= 1,
 		VROverlayTransform_SystemOverlay			= 2,
@@ -2755,17 +3010,17 @@ namespace vr
 
 		/** Sets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */
 		virtual EVROverlayError SetOverlayTextureBounds( VROverlayHandle_t ulOverlayHandle, const VRTextureBounds_t *pOverlayTextureBounds ) = 0;
 
 		/** Gets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */
 		virtual EVROverlayError GetOverlayTextureBounds( VROverlayHandle_t ulOverlayHandle, VRTextureBounds_t *pOverlayTextureBounds ) = 0;
 
 		/** Gets render model to draw behind this overlay */
-		virtual uint32_t GetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, HmdColor_t *pColor, vr::EVROverlayError *pError ) = 0;
+		virtual uint32_t GetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, HmdColor_t *pColor, vr::EVROverlayError *pError ) = 0;
 
 		/** Sets render model to draw behind this overlay and the vertex color to use, pass null for pColor to match the overlays vertex color. 
 			The model is scaled by the same amount as the overlay, with a default of 1m. */
 		virtual vr::EVROverlayError SetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, const char *pchRenderModel, const HmdColor_t *pColor ) = 0;
 
 		/** Returns the transform type of this overlay. */
 		virtual EVROverlayError GetOverlayTransformType( VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType ) = 0;
 
@@ -2781,17 +3036,17 @@ namespace vr
 		/** Gets the transform if it is relative to a tracked device. Returns an error if the transform is some other type. */
 		virtual EVROverlayError GetOverlayTransformTrackedDeviceRelative( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform ) = 0;
 
 		/** Sets the transform to draw the overlay on a rendermodel component mesh instead of a quad. This will only draw when the system is
 		* drawing the device. Overlays with this transform type cannot receive mouse events. */
 		virtual EVROverlayError SetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, const char *pchComponentName ) = 0;
 
 		/** Gets the transform information when the overlay is rendering on a component. */
-		virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize ) = 0;
+		virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, VR_OUT_STRING() char *pchComponentName, uint32_t unComponentNameSize ) = 0;
 
 		/** Gets the transform if it is relative to another overlay. Returns an error if the transform is some other type. */
 		virtual vr::EVROverlayError GetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0;
 		
 		/** Sets the transform to relative to the transform of the specified overlay. This overlays visibility will also track the parents visibility */
 		virtual vr::EVROverlayError SetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, const HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0;
 
 		/** Shows the VR overlay.  For dashboard overlays, only the Dashboard Manager is allowed to call this. */
@@ -2827,23 +3082,16 @@ namespace vr
 		/** Sets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is
 		* typically the size of the underlying UI in pixels (not in world space). */
 		virtual EVROverlayError SetOverlayMouseScale( VROverlayHandle_t ulOverlayHandle, const HmdVector2_t *pvecMouseScale ) = 0;
 
 		/** Computes the overlay-space pixel coordinates of where the ray intersects the overlay with the
 		* specified settings. Returns false if there is no intersection. */
 		virtual bool ComputeOverlayIntersection( VROverlayHandle_t ulOverlayHandle, const VROverlayIntersectionParams_t *pParams, VROverlayIntersectionResults_t *pResults ) = 0;
 
-		/** Processes mouse input from the specified controller as though it were a mouse pointed at a compositor overlay with the
-		* specified settings. The controller is treated like a laser pointer on the -z axis. The point where the laser pointer would
-		* intersect with the overlay is the mouse position, the trigger is left mouse, and the track pad is right mouse. 
-		*
-		* Return true if the controller is pointed at the overlay and an event was generated. */
-		virtual bool HandleControllerOverlayInteractionAsMouse( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex ) = 0;
-
 		/** Returns true if the specified overlay is the hover target. An overlay is the hover target when it is the last overlay "moused over" 
 		* by the virtual mouse pointer */
 		virtual bool IsHoverTargetOverlay( VROverlayHandle_t ulOverlayHandle ) = 0;
 
 		/** Returns the current Gamepad focus overlay */
 		virtual vr::VROverlayHandle_t GetGamepadFocusOverlay() = 0;
 
 		/** Sets the current Gamepad focus overlay */
@@ -2853,16 +3101,22 @@ namespace vr
 		* to point back to the "from" overlay. If an overlay's neighbor is set to invalid both
 		* ends will be cleared */
 		virtual EVROverlayError SetOverlayNeighbor( EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo ) = 0;
 
 		/** Changes the Gamepad focus from one overlay to one of its neighbors. Returns VROverlayError_NoNeighbor if there is no
 		* neighbor in that direction */
 		virtual EVROverlayError MoveGamepadFocusToNeighbor( EOverlayDirection eDirection, VROverlayHandle_t ulFrom ) = 0;
 
+		/** Sets the analog input to Dual Analog coordinate scale for the specified overlay. */
+		virtual EVROverlayError SetOverlayDualAnalogTransform( VROverlayHandle_t ulOverlay, EDualAnalogWhich eWhich, const HmdVector2_t & vCenter, float fRadius ) = 0;
+
+		/** Gets the analog input to Dual Analog coordinate scale for the specified overlay. */
+		virtual EVROverlayError GetOverlayDualAnalogTransform( VROverlayHandle_t ulOverlay, EDualAnalogWhich eWhich, HmdVector2_t *pvCenter, float *pfRadius ) = 0;
+
 		// ---------------------------------------------
 		// Overlay texture methods
 		// ---------------------------------------------
 
 		/** Texture to draw for the overlay. This function can only be called by the overlay's creator or renderer process (see SetOverlayRenderingPid) .
 		*
 		* OpenGL dirty state:
 		*	glBindTexture
@@ -2957,19 +3211,22 @@ namespace vr
 		virtual EVROverlayError GetOverlayFlags( VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags ) = 0;
 
 		// ---------------------------------------------
 		// Message box methods
 		// ---------------------------------------------
 
 		/** Show the message overlay. This will block and return you a result. **/
 		virtual VRMessageOverlayResponse ShowMessageOverlay( const char* pchText, const char* pchCaption, const char* pchButton0Text, const char* pchButton1Text = nullptr, const char* pchButton2Text = nullptr, const char* pchButton3Text = nullptr ) = 0;
+
+		/** If the calling process owns the overlay and it's open, this will close it. **/
+		virtual void CloseMessageOverlay() = 0;
 	};
 
-	static const char * const IVROverlay_Version = "IVROverlay_016";
+	static const char * const IVROverlay_Version = "IVROverlay_018";
 
 } // namespace vr
 
 // ivrrendermodels.h
 namespace vr
 {
 
 static const char * const k_pch_Controller_Component_GDC2015 = "gdc2015";   // Canonical coordinate system of the gdc 2015 wired controller, provided for backwards compatibility
@@ -3379,17 +3636,17 @@ public:
 
 	/** Loads the specified resource into the provided buffer if large enough.
 	* Returns the size in bytes of the buffer required to hold the specified resource. */
 	virtual uint32_t LoadSharedResource( const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen ) = 0;
 
 	/** Provides the full path to the specified resource. Resource names can include named directories for
 	* drivers and other things, and this resolves all of those and returns the actual physical path. 
 	* pchResourceTypeDirectory is the subdirectory of resources to look in. */
-	virtual uint32_t GetResourceFullPath( const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen ) = 0;
+	virtual uint32_t GetResourceFullPath( const char *pchResourceName, const char *pchResourceTypeDirectory, VR_OUT_STRING() char *pchPathBuffer, uint32_t unBufferLen ) = 0;
 };
 
 static const char * const IVRResources_Version = "IVRResources_001";
 
 
 }
 // ivrdrivermanager.h
 namespace vr
@@ -3397,16 +3654,18 @@ namespace vr
 
 class IVRDriverManager
 {
 public:
 	virtual uint32_t GetDriverCount() const = 0;
 
 	/** Returns the length of the number of bytes necessary to hold this string including the trailing null. */
 	virtual uint32_t GetDriverName( vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0;
+
+	virtual DriverHandle_t GetDriverHandle( const char *pchDriverName ) = 0;
 };
 
 static const char * const IVRDriverManager_Version = "IVRDriverManager_001";
 
 } // namespace vr
 
 
 // End
@@ -3417,18 +3676,20 @@ static const char * const IVRDriverManag
 namespace vr
 {
 	/** Finds the active installation of the VR API and initializes it. The provided path must be absolute
 	* or relative to the current working directory. These are the local install versions of the equivalent
 	* functions in steamvr.h and will work without a local Steam install.
 	*
 	* This path is to the "root" of the VR API install. That's the directory with
 	* the "drivers" directory and a platform (i.e. "win32") directory in it, not the directory with the DLL itself.
+	*
+	* pStartupInfo is reserved for future use.
 	*/
-	inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType );
+	inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo = nullptr );
 
 	/** unloads vrclient.dll. Any interface pointers from the interface are
 	* invalid after this point */
 	inline void VR_Shutdown();
 
 	/** Returns true if there is an HMD attached. This check is as lightweight as possible and
 	* can be called outside of VR_Init/VR_Shutdown. It should be used when an application wants
 	* to know if initializing VR is a possibility but isn't ready to take that step yet.
@@ -3688,27 +3949,27 @@ namespace vr
 		m_pVRExtendedDisplay = nullptr;
 		m_pVRSettings = nullptr;
 		m_pVRApplications = nullptr;
 		m_pVRTrackedCamera = nullptr;
 		m_pVRResources = nullptr;
 		m_pVRScreenshots = nullptr;
 		m_pVRDriverManager = nullptr;
 	}
-
-	VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal( EVRInitError *peError, EVRApplicationType eApplicationType );
+	
+	VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal2( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo );
 	VR_INTERFACE void VR_CALLTYPE VR_ShutdownInternal();
 
 	/** Finds the active installation of vrclient.dll and initializes it */
-	inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType )
+	inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo )
 	{
 		IVRSystem *pVRSystem = nullptr;
 
 		EVRInitError eError;
-		VRToken() = VR_InitInternal( &eError, eApplicationType );
+		VRToken() = VR_InitInternal2( &eError, eApplicationType, pStartupInfo );
 		COpenVRContext &ctx = OpenVRInternal_ModuleContext();
 		ctx.Clear();
 
 		if ( eError == VRInitError_None )
 		{
 			if ( VR_IsInterfaceVersionValid( IVRSystem_Version ) )
 			{
 				pVRSystem = VRSystem();
--- a/gfx/vr/openvr/src/hmderrors_public.cpp
+++ b/gfx/vr/openvr/src/hmderrors_public.cpp
@@ -8,86 +8,90 @@ using namespace vr;
 
 #define RETURN_ENUM_AS_STRING(enumValue) case enumValue: return #enumValue;
 
 
 const char *GetEnglishStringForHmdError( vr::EVRInitError eError )
 {
 	switch( eError )
 	{
-	case VRInitError_None:						return "No Error (0)";
+	case VRInitError_None:								return "No Error (0)";
 
-	case VRInitError_Init_InstallationNotFound:	return "Installation Not Found (100)";
-	case VRInitError_Init_InstallationCorrupt:	return "Installation Corrupt (101)";
-	case VRInitError_Init_VRClientDLLNotFound:	return "vrclient Shared Lib Not Found (102)";
-	case VRInitError_Init_FileNotFound:			return "File Not Found (103)";
-	case VRInitError_Init_FactoryNotFound:		return "Factory Function Not Found (104)";
-	case VRInitError_Init_InterfaceNotFound:	return "Interface Not Found (105)";
-	case VRInitError_Init_InvalidInterface:		return "Invalid Interface (106)";
-	case VRInitError_Init_UserConfigDirectoryInvalid: return "User Config Directory Invalid (107)";
-	case VRInitError_Init_HmdNotFound:			return "Hmd Not Found (108)";
-	case VRInitError_Init_NotInitialized:		return "Not Initialized (109)";
-	case VRInitError_Init_PathRegistryNotFound:	return "Installation path could not be located (110)";
-	case VRInitError_Init_NoConfigPath:			return "Config path could not be located (111)";
-	case VRInitError_Init_NoLogPath:			return "Log path could not be located (112)";
-	case VRInitError_Init_PathRegistryNotWritable: return "Unable to write path registry (113)";
-	case VRInitError_Init_AppInfoInitFailed:	return "App info manager init failed (114)";
-	case VRInitError_Init_Retry:				return "Internal Retry (115)";
-	case VRInitError_Init_InitCanceledByUser:	return "User Canceled Init (116)";
-	case VRInitError_Init_AnotherAppLaunching:	return "Another app was already launching (117)";
-	case VRInitError_Init_SettingsInitFailed:	return "Settings manager init failed (118)";
-	case VRInitError_Init_ShuttingDown:			return "VR system shutting down (119)";
-	case VRInitError_Init_TooManyObjects:		return "Too many tracked objects (120)";
-	case VRInitError_Init_NoServerForBackgroundApp: return "Not starting vrserver for background app (121)";
-	case VRInitError_Init_NotSupportedWithCompositor: return "The requested interface is incompatible with the compositor and the compositor is running (122)";
-	case VRInitError_Init_NotAvailableToUtilityApps: return "This interface is not available to utility applications (123)";
-	case VRInitError_Init_Internal:				return "vrserver internal error (124)";
-	case VRInitError_Init_HmdDriverIdIsNone:	return "Hmd DriverId is invalid (125)";
+	case VRInitError_Init_InstallationNotFound:			return "Installation Not Found (100)";
+	case VRInitError_Init_InstallationCorrupt:			return "Installation Corrupt (101)";
+	case VRInitError_Init_VRClientDLLNotFound:			return "vrclient Shared Lib Not Found (102)";
+	case VRInitError_Init_FileNotFound:					return "File Not Found (103)";
+	case VRInitError_Init_FactoryNotFound:				return "Factory Function Not Found (104)";
+	case VRInitError_Init_InterfaceNotFound:			return "Interface Not Found (105)";
+	case VRInitError_Init_InvalidInterface:				return "Invalid Interface (106)";
+	case VRInitError_Init_UserConfigDirectoryInvalid:	return "User Config Directory Invalid (107)";
+	case VRInitError_Init_HmdNotFound:					return "Hmd Not Found (108)";
+	case VRInitError_Init_NotInitialized:				return "Not Initialized (109)";
+	case VRInitError_Init_PathRegistryNotFound:			return "Installation path could not be located (110)";
+	case VRInitError_Init_NoConfigPath:					return "Config path could not be located (111)";
+	case VRInitError_Init_NoLogPath:					return "Log path could not be located (112)";
+	case VRInitError_Init_PathRegistryNotWritable:		return "Unable to write path registry (113)";
+	case VRInitError_Init_AppInfoInitFailed:			return "App info manager init failed (114)";
+	case VRInitError_Init_Retry:						return "Internal Retry (115)";
+	case VRInitError_Init_InitCanceledByUser:			return "User Canceled Init (116)";
+	case VRInitError_Init_AnotherAppLaunching:			return "Another app was already launching (117)";
+	case VRInitError_Init_SettingsInitFailed:			return "Settings manager init failed (118)";
+	case VRInitError_Init_ShuttingDown:					return "VR system shutting down (119)";
+	case VRInitError_Init_TooManyObjects:				return "Too many tracked objects (120)";
+	case VRInitError_Init_NoServerForBackgroundApp:		return "Not starting vrserver for background app (121)";
+	case VRInitError_Init_NotSupportedWithCompositor:	return "The requested interface is incompatible with the compositor and the compositor is running (122)";
+	case VRInitError_Init_NotAvailableToUtilityApps:	return "This interface is not available to utility applications (123)";
+	case VRInitError_Init_Internal:						return "vrserver internal error (124)";
+	case VRInitError_Init_HmdDriverIdIsNone:			return "Hmd DriverId is invalid (125)";
 	case VRInitError_Init_HmdNotFoundPresenceFailed:	return "Hmd Not Found Presence Failed (126)";
-	case VRInitError_Init_VRMonitorNotFound: return "VR Monitor Not Found (127)";
-	case VRInitError_Init_VRMonitorStartupFailed: return "VR Monitor startup failed (128)";
+	case VRInitError_Init_VRMonitorNotFound:			return "VR Monitor Not Found (127)";
+	case VRInitError_Init_VRMonitorStartupFailed:		return "VR Monitor startup failed (128)";
 	case VRInitError_Init_LowPowerWatchdogNotSupported: return "Low Power Watchdog Not Supported (129)";
-	case VRInitError_Init_InvalidApplicationType: return "Invalid Application Type (130)";
-	case VRInitError_Init_NotAvailableToWatchdogApps: return "Not available to watchdog apps (131)";
-	case VRInitError_Init_WatchdogDisabledInSettings: return "Watchdog disabled in settings (132)";
-	case VRInitError_Init_VRDashboardNotFound: return "VR Dashboard Not Found (133)";
-	case VRInitError_Init_VRDashboardStartupFailed: return "VR Dashboard startup failed (134)";
-	case VRInitError_Init_VRHomeNotFound: return "VR Home Not Found (135)";
-	case VRInitError_Init_VRHomeStartupFailed: return "VR home startup failed (136)";
+	case VRInitError_Init_InvalidApplicationType:		return "Invalid Application Type (130)";
+	case VRInitError_Init_NotAvailableToWatchdogApps:	return "Not available to watchdog apps (131)";
+	case VRInitError_Init_WatchdogDisabledInSettings:	return "Watchdog disabled in settings (132)";
+	case VRInitError_Init_VRDashboardNotFound:			return "VR Dashboard Not Found (133)";
+	case VRInitError_Init_VRDashboardStartupFailed:		return "VR Dashboard startup failed (134)";
+	case VRInitError_Init_VRHomeNotFound:				return "VR Home Not Found (135)";
+	case VRInitError_Init_VRHomeStartupFailed:			return "VR home startup failed (136)";
+	case VRInitError_Init_RebootingBusy:				return "Rebooting In Progress (137)";
+	case VRInitError_Init_FirmwareUpdateBusy:			return "Firmware Update In Progress (138)";
+	case VRInitError_Init_FirmwareRecoveryBusy:			return "Firmware Recovery In Progress (139)";
+	case VRInitError_Init_USBServiceBusy:				return "USB Service Busy (140)";
 
-	case VRInitError_Driver_Failed:				return "Driver Failed (200)";
-	case VRInitError_Driver_Unknown:			return "Driver Not Known (201)";
-	case VRInitError_Driver_HmdUnknown:			return "HMD Not Known (202)";
-	case VRInitError_Driver_NotLoaded:			return "Driver Not Loaded (203)";
-	case VRInitError_Driver_RuntimeOutOfDate:	return "Driver runtime is out of date (204)";
-	case VRInitError_Driver_HmdInUse:			return "HMD already in use by another application (205)";
-	case VRInitError_Driver_NotCalibrated:		return "Device is not calibrated (206)";
-	case VRInitError_Driver_CalibrationInvalid: return "Device Calibration is invalid (207)";
-	case VRInitError_Driver_HmdDisplayNotFound: return "HMD detected over USB, but Monitor not found (208)";
-	case VRInitError_Driver_TrackedDeviceInterfaceUnknown: return "Driver Tracked Device Interface unknown (209)";
-	// case VRInitError_Driver_HmdDisplayNotFoundAfterFix: return "HMD detected over USB, but Monitor not found after attempt to fix (210)"; // taken out upon Ben's request: He thinks that there is no need to separate that error from 208
-	case VRInitError_Driver_HmdDriverIdOutOfBounds: return "Hmd DriverId is our of bounds (211)";
-	case VRInitError_Driver_HmdDisplayMirrored: return "HMD detected over USB, but Monitor may be mirrored instead of extended (212)";
+	case VRInitError_Driver_Failed:							return "Driver Failed (200)";
+	case VRInitError_Driver_Unknown:						return "Driver Not Known (201)";
+	case VRInitError_Driver_HmdUnknown:						return "HMD Not Known (202)";
+	case VRInitError_Driver_NotLoaded:						return "Driver Not Loaded (203)";
+	case VRInitError_Driver_RuntimeOutOfDate:				return "Driver runtime is out of date (204)";
+	case VRInitError_Driver_HmdInUse:						return "HMD already in use by another application (205)";
+	case VRInitError_Driver_NotCalibrated:					return "Device is not calibrated (206)";
+	case VRInitError_Driver_CalibrationInvalid:				return "Device Calibration is invalid (207)";
+	case VRInitError_Driver_HmdDisplayNotFound:				return "HMD detected over USB, but Monitor not found (208)";
+	case VRInitError_Driver_TrackedDeviceInterfaceUnknown:	return "Driver Tracked Device Interface unknown (209)";
+	// case VRInitError_Driver_HmdDisplayNotFoundAfterFix:	return "HMD detected over USB, but Monitor not found after attempt to fix (210)"; // taken out upon Ben's request: He thinks that there is no need to separate that error from 208
+	case VRInitError_Driver_HmdDriverIdOutOfBounds:			return "Hmd DriverId is our of bounds (211)";
+	case VRInitError_Driver_HmdDisplayMirrored:				return "HMD detected over USB, but Monitor may be mirrored instead of extended (212)";
 
-	case VRInitError_IPC_ServerInitFailed:		return "VR Server Init Failed (300)";
-	case VRInitError_IPC_ConnectFailed:			return "Connect to VR Server Failed (301)";
-	case VRInitError_IPC_SharedStateInitFailed: return "Shared IPC State Init Failed (302)";
-	case VRInitError_IPC_CompositorInitFailed:	return "Shared IPC Compositor Init Failed (303)";
-	case VRInitError_IPC_MutexInitFailed:		return "Shared IPC Mutex Init Failed (304)";
-	case VRInitError_IPC_Failed:				return "Shared IPC Failed (305)";
+	case VRInitError_IPC_ServerInitFailed:						return "VR Server Init Failed (300)";
+	case VRInitError_IPC_ConnectFailed:							return "Connect to VR Server Failed (301)";
+	case VRInitError_IPC_SharedStateInitFailed:					return "Shared IPC State Init Failed (302)";
+	case VRInitError_IPC_CompositorInitFailed:					return "Shared IPC Compositor Init Failed (303)";
+	case VRInitError_IPC_MutexInitFailed:						return "Shared IPC Mutex Init Failed (304)";
+	case VRInitError_IPC_Failed:								return "Shared IPC Failed (305)";
 	case VRInitError_IPC_CompositorConnectFailed:				return "Shared IPC Compositor Connect Failed (306)";
 	case VRInitError_IPC_CompositorInvalidConnectResponse:		return "Shared IPC Compositor Invalid Connect Response (307)";
 	case VRInitError_IPC_ConnectFailedAfterMultipleAttempts:	return "Shared IPC Connect Failed After Multiple Attempts (308)";
 
-	case VRInitError_Compositor_Failed:						return "Compositor failed to initialize (400)";
-	case VRInitError_Compositor_D3D11HardwareRequired:		return "Compositor failed to find DX11 hardware (401)";
-	case VRInitError_Compositor_FirmwareRequiresUpdate:		return "Compositor requires mandatory firmware update (402)";
-	case VRInitError_Compositor_OverlayInitFailed:			return "Compositor initialization succeeded, but overlay init failed (403)";
-	case VRInitError_Compositor_ScreenshotsInitFailed:			return "Compositor initialization succeeded, but screenshot init failed (404)";
-	case VRInitError_Compositor_UnableToCreateDevice:			return "Compositor unable to create graphics device (405)";
+	case VRInitError_Compositor_Failed:					return "Compositor failed to initialize (400)";
+	case VRInitError_Compositor_D3D11HardwareRequired:	return "Compositor failed to find DX11 hardware (401)";
+	case VRInitError_Compositor_FirmwareRequiresUpdate:	return "Compositor requires mandatory firmware update (402)";
+	case VRInitError_Compositor_OverlayInitFailed:		return "Compositor initialization succeeded, but overlay init failed (403)";
+	case VRInitError_Compositor_ScreenshotsInitFailed:	return "Compositor initialization succeeded, but screenshot init failed (404)";
+	case VRInitError_Compositor_UnableToCreateDevice:	return "Compositor unable to create graphics device (405)";
 
 	// Oculus
 	case VRInitError_VendorSpecific_UnableToConnectToOculusRuntime:	return "Unable to connect to Oculus Runtime (1000)";
 
 	// Lighthouse
 	case VRInitError_VendorSpecific_HmdFound_CantOpenDevice:				return "HMD found, but can not open device (1101)";
 	case VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart:	return "HMD found, but unable to request config (1102)";
 	case VRInitError_VendorSpecific_HmdFound_NoStoredConfig:				return "HMD found, but no stored config (1103)";
@@ -100,21 +104,17 @@ const char *GetEnglishStringForHmdError(
 	case VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart:		return "HMD found, but problems with the data (1109)";
 	case VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext:		return "HMD found, but problems with the data (1110)";
 	case VRInitError_VendorSpecific_HmdFound_UserDataAddressRange:			return "HMD found, but problems with the data (1111)";
 	case VRInitError_VendorSpecific_HmdFound_UserDataError:					return "HMD found, but problems with the data (1112)";
 
 	case VRInitError_Steam_SteamInstallationNotFound: return "Unable to find Steam installation (2000)";
 
 	default:
-		{
-			static char buf[128];
-			sprintf( buf, "Unknown error (%d)", eError );
-			return buf;
-		}
+		return GetIDForVRInitError( eError );
 	}
 
 }
 
 
 const char *GetIDForVRInitError( vr::EVRInitError eError )
 {
 	switch( eError )
@@ -142,29 +142,33 @@ const char *GetIDForVRInitError( vr::EVR
 		RETURN_ENUM_AS_STRING( VRInitError_Init_AnotherAppLaunching );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_SettingsInitFailed );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_ShuttingDown );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_TooManyObjects );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_NoServerForBackgroundApp );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_NotSupportedWithCompositor );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_NotAvailableToUtilityApps );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_Internal );
+		RETURN_ENUM_AS_STRING( VRInitError_Init_HmdDriverIdIsNone );
+		RETURN_ENUM_AS_STRING( VRInitError_Init_HmdNotFoundPresenceFailed );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_VRMonitorNotFound );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_VRMonitorStartupFailed );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_LowPowerWatchdogNotSupported );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_InvalidApplicationType );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_NotAvailableToWatchdogApps );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_WatchdogDisabledInSettings );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_VRDashboardNotFound );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_VRDashboardStartupFailed );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_VRHomeNotFound );
 		RETURN_ENUM_AS_STRING( VRInitError_Init_VRHomeStartupFailed );
-
-		RETURN_ENUM_AS_STRING( VRInitError_Init_HmdDriverIdIsNone );
-		RETURN_ENUM_AS_STRING( VRInitError_Init_HmdNotFoundPresenceFailed );
+		RETURN_ENUM_AS_STRING( VRInitError_Init_RebootingBusy );
+		RETURN_ENUM_AS_STRING( VRInitError_Init_FirmwareUpdateBusy );
+		RETURN_ENUM_AS_STRING( VRInitError_Init_FirmwareRecoveryBusy );
+		RETURN_ENUM_AS_STRING( VRInitError_Init_USBServiceBusy );
+		RETURN_ENUM_AS_STRING( VRInitError_Init_VRWebHelperStartupFailed );
 
 		RETURN_ENUM_AS_STRING( VRInitError_Driver_Failed );
 		RETURN_ENUM_AS_STRING( VRInitError_Driver_Unknown );
 		RETURN_ENUM_AS_STRING( VRInitError_Driver_HmdUnknown);
 		RETURN_ENUM_AS_STRING( VRInitError_Driver_NotLoaded);
 		RETURN_ENUM_AS_STRING( VRInitError_Driver_RuntimeOutOfDate);
 		RETURN_ENUM_AS_STRING( VRInitError_Driver_HmdInUse);
 		RETURN_ENUM_AS_STRING( VRInitError_Driver_NotCalibrated);
@@ -187,18 +191,19 @@ const char *GetIDForVRInitError( vr::EVR
 
 		RETURN_ENUM_AS_STRING( VRInitError_Compositor_Failed );
 		RETURN_ENUM_AS_STRING( VRInitError_Compositor_D3D11HardwareRequired );
 		RETURN_ENUM_AS_STRING( VRInitError_Compositor_FirmwareRequiresUpdate );
 		RETURN_ENUM_AS_STRING( VRInitError_Compositor_OverlayInitFailed );
 		RETURN_ENUM_AS_STRING( VRInitError_Compositor_ScreenshotsInitFailed );
 		RETURN_ENUM_AS_STRING( VRInitError_Compositor_UnableToCreateDevice );
 
-		// Oculus
+		// Vendor-specific errors
 		RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_UnableToConnectToOculusRuntime);
+		RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_WindowsNotInDevMode );
 
 		// Lighthouse
 		RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_CantOpenDevice);
 		RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart);
 		RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_NoStoredConfig);
 		RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck );
 		RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_ConfigTooBig );
 		RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_ConfigTooSmall );
--- a/gfx/vr/openvr/src/openvr_api_public.cpp
+++ b/gfx/vr/openvr/src/openvr_api_public.cpp
@@ -2,86 +2,88 @@
 #define VR_API_EXPORT 1
 #include "openvr.h"
 #include "ivrclientcore.h"
 #include "pathtools_public.h"
 #include "sharedlibtools_public.h"
 #include "envvartools_public.h"
 #include "hmderrors_public.h"
 #include "vrpathregistry_public.h"
+#include <mutex>
 
 using vr::EVRInitError;
 using vr::IVRSystem;
 using vr::IVRClientCore;
 using vr::VRInitError_None;
 
 namespace vr
 {
 
 static void *g_pVRModule = NULL;
 static IVRClientCore *g_pHmdSystem = NULL;
+static std::recursive_mutex g_mutexSystem;
 
 
 typedef void* (*VRClientCoreFactoryFn)(const char *pInterfaceName, int *pReturnCode);
 
 static uint32_t g_nVRToken = 0;
 
 uint32_t VR_GetInitToken()
 {
 	return g_nVRToken;
 }
 
 EVRInitError VR_LoadHmdSystemInternal();
 void CleanupInternalInterfaces();
 
 
-uint32_t VR_InitInternal( EVRInitError *peError, vr::EVRApplicationType eApplicationType )
+uint32_t VR_InitInternal2( EVRInitError *peError, vr::EVRApplicationType eApplicationType, const char *pStartupInfo )
 {
+	std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
 	EVRInitError err = VR_LoadHmdSystemInternal();
-	if (err != vr::VRInitError_None)
+	if ( err == vr::VRInitError_None )
 	{
-		SharedLib_Unload(g_pVRModule);
+		err = g_pHmdSystem->Init( eApplicationType );
+	}
+
+	if ( peError )
+		*peError = err;
+
+	if ( err != VRInitError_None )
+	{
+		SharedLib_Unload( g_pVRModule );
 		g_pHmdSystem = NULL;
 		g_pVRModule = NULL;
 
-		if (peError)
-			*peError = err;
-
 		return 0;
 	}
 
-	err = g_pHmdSystem->Init(eApplicationType);
-	if (err != VRInitError_None)
-	{
-		SharedLib_Unload(g_pVRModule);
-		g_pHmdSystem = NULL;
-		g_pVRModule = NULL;
+	return ++g_nVRToken;
+}
 
-		if (peError)
-			*peError = err;
+VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal( EVRInitError *peError, EVRApplicationType eApplicationType );
 
-		return 0;
-	}
-
-	if (peError)
-		*peError = VRInitError_None;
-
-	return ++g_nVRToken;
+uint32_t VR_InitInternal( EVRInitError *peError, vr::EVRApplicationType eApplicationType )
+{
+	return VR_InitInternal2( peError, eApplicationType, nullptr );
 }
 
 void VR_ShutdownInternal()
 {
-	if (g_pHmdSystem)
+	std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+	
+	if ( g_pHmdSystem )
 	{
 		g_pHmdSystem->Cleanup();
 		g_pHmdSystem = NULL;
 	}
-	if (g_pVRModule)
+	if ( g_pVRModule )
 	{
-		SharedLib_Unload(g_pVRModule);
+		SharedLib_Unload( g_pVRModule );
 		g_pVRModule = NULL;
 	}
 
 #if !defined( VR_API_PUBLIC )
 	CleanupInternalInterfaces();
 #endif
 
 	++g_nVRToken;
@@ -147,38 +149,44 @@ EVRInitError VR_LoadHmdSystemInternal()
 
 	g_pVRModule = pMod;
 	return VRInitError_None;
 }
 
 
 void *VR_GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError)
 {
+	std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
 	if (!g_pHmdSystem)
 	{
 		if (peError)
 			*peError = vr::VRInitError_Init_NotInitialized;
 		return NULL;
 	}
 
 	return g_pHmdSystem->GetGenericInterface(pchInterfaceVersion, peError);
 }
 
 bool VR_IsInterfaceVersionValid(const char *pchInterfaceVersion)
 {
+	std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
 	if (!g_pHmdSystem)
 	{
 		return false;
 	}
 
 	return g_pHmdSystem->IsInterfaceVersionValid(pchInterfaceVersion) == VRInitError_None;
 }
 
 bool VR_IsHmdPresent()
 {
+	std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
 	if( g_pHmdSystem )
 	{
 		// if we're already initialized, just call through
 		return g_pHmdSystem->BIsHmdPresent();
 	}
 	else
 	{
 		// otherwise we need to do a bit more work
@@ -194,16 +202,18 @@ bool VR_IsHmdPresent()
 
 		return bHasHmd;
 	}
 }
 
 /** Returns true if the OpenVR runtime is installed. */
 bool VR_IsRuntimeInstalled()
 {
+	std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
 	if( g_pHmdSystem )
 	{
 		// if we're already initialized, OpenVR is obviously installed
 		return true;
 	}
 	else
 	{
 		// otherwise we need to do a bit more work
@@ -250,26 +260,30 @@ const char *VR_RuntimePath()
 
 	return sRuntimePath.c_str();
 }
 
 
 /** Returns the symbol version of an HMD error. */
 const char *VR_GetVRInitErrorAsSymbol( EVRInitError error )
 {
+	std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
 	if( g_pHmdSystem )
 		return g_pHmdSystem->GetIDForVRInitError( error );
 	else
 		return GetIDForVRInitError( error );
 }
 
 
 /** Returns the english string version of an HMD error. */
 const char *VR_GetVRInitErrorAsEnglishDescription( EVRInitError error )
 {
+	std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
 	if ( g_pHmdSystem )
 		return g_pHmdSystem->GetEnglishStringForHmdError( error );
 	else
 		return GetEnglishStringForHmdError( error );
 }
 
 
 VR_INTERFACE const char *VR_CALLTYPE VR_GetStringForHmdError( vr::EVRInitError error );
--- a/gfx/vr/openvr/src/pathtools_public.cpp
+++ b/gfx/vr/openvr/src/pathtools_public.cpp
@@ -183,29 +183,26 @@ bool Path_IsAbsolute( const std::string 
 		return true;
 #endif
 
 	return false;
 }
 
 
 /** Makes an absolute path from a relative path and a base path */
-std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath, char slash )
+std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath )
 {
-	if( slash == 0 )
-		slash = Path_GetSlash();
-
 	if( Path_IsAbsolute( sRelativePath ) )
 		return sRelativePath;
 	else
 	{
 		if( !Path_IsAbsolute( sBasePath ) )
 			return "";
 
-		std::string sCompacted = Path_Compact( Path_Join( sBasePath, sRelativePath, slash ), slash );
+		std::string sCompacted = Path_Compact( Path_Join( sBasePath, sRelativePath ) );
 		if( Path_IsAbsolute( sCompacted ) )
 			return sCompacted;
 		else
 			return "";
 	}
 }
 
 
@@ -459,20 +456,21 @@ bool Path_IsDirectory( const std::string
 	return (buf.st_mode & _S_IFDIR) != 0;
 #endif
 }
 
 /** returns true if the specified path represents an app bundle */
 bool Path_IsAppBundle( const std::string & sPath )
 {
 #if defined(OSX)
-	NSBundle *bundle = [ NSBundle bundleWithPath: [ NSString stringWithUTF8String:sPath.c_str() ] ];
-	bool bisAppBundle = ( nullptr != bundle );
-	[ bundle release ];
-	return bisAppBundle;
+	@autoreleasepool {
+		NSBundle *bundle = [ NSBundle bundleWithPath: [ NSString stringWithUTF8String:sPath.c_str() ] ];
+		bool bisAppBundle = ( nullptr != bundle );
+		return bisAppBundle;
+	}
 #else
 	return false;
 #endif
 }
 
 //-----------------------------------------------------------------------------
 // Purpose: returns true if the the path exists
 //-----------------------------------------------------------------------------
@@ -650,17 +648,17 @@ bool Path_WriteBinaryFile(const std::str
 #endif
 
 	size_t written = 0;
 	if (f != NULL) {
 		written = fwrite(pData, sizeof(unsigned char), nSize, f);
 		fclose(f);
 	}
 
-	return written = nSize ? true : false;
+	return written == nSize ? true : false;
 }
 
 std::string Path_ReadTextFile( const std::string &strFilename )
 {
 	// doing it this way seems backwards, but I don't
 	// see an easy way to do this with C/C++ style IO
 	// that isn't worse...
 	int size;
--- a/gfx/vr/openvr/src/pathtools_public.h
+++ b/gfx/vr/openvr/src/pathtools_public.h
@@ -30,17 +30,17 @@ std::string Path_StripExtension( const s
 
 /** returns just extension of the provided filename (if any). */
 std::string Path_GetExtension( const std::string & sPath );
 
 /** Returns true if the path is absolute */
 bool Path_IsAbsolute( const std::string & sPath );
 
 /** Makes an absolute path from a relative path and a base path */
-std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath, char slash = 0 );
+std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath );
 
 /** Fixes the directory separators for the current platform.
 * If slash is unspecified the native path separator of the current platform
 * will be used. */
 std::string Path_FixSlashes( const std::string & sPath, char slash = 0 );
 
 /** Returns the path separator for the current platform */
 char Path_GetSlash();
--- a/gfx/vr/openvr/src/strtools_public.cpp
+++ b/gfx/vr/openvr/src/strtools_public.cpp
@@ -1,13 +1,15 @@
 //========= Copyright Valve Corporation ============//
 #include "strtools_public.h"
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sstream>
+#include <iostream>
 
 //-----------------------------------------------------------------------------
 // Purpose:
 //-----------------------------------------------------------------------------
 bool StringHasPrefix( const std::string & sString, const std::string & sPrefix )
 {
 	return 0 == strnicmp( sString.c_str(), sPrefix.c_str(), sPrefix.length() );
 }
@@ -137,18 +139,18 @@ std::wstring UTF8to16(const char * in)
 		}
 	}
 	return out;
 }
 
 
 void strcpy_safe( char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource )
 {
-	pchBuffer[ unBufferSizeBytes - 1 ] = '\0';
 	strncpy( pchBuffer, pchSource, unBufferSizeBytes - 1 );
+	pchBuffer[unBufferSizeBytes - 1] = '\0';
 }
 
 
 // --------------------------------------------------------------------
 // Purpose: converts a string to upper case
 // --------------------------------------------------------------------
 std::string StringToUpper( const std::string & sString )
 {
@@ -192,23 +194,16 @@ uint32_t ReturnStdString( const std::str
 	else
 	{
 		memcpy( pchBuffer, sValue.c_str(), unLen );
 	}
 
 	return unLen;
 }
 
-void BufferToStdString( std::string & sDest, const char *pchBuffer, uint32_t unBufferLen )
-{
-	sDest.resize( unBufferLen + 1 );
-	memcpy( const_cast< char* >( sDest.c_str() ), pchBuffer, unBufferLen );
-	const_cast< char* >( sDest.c_str() )[ unBufferLen ] = '\0';
-}
-
 // Commented out by Mozilla, please see README.mozilla
 /** Returns a std::string from a uint64_t */
 /*
 std::string Uint64ToString( uint64_t ulValue )
 {
 	char buf[ 22 ];
 #if defined( _WIN32 )
 	sprintf_s( buf, "%llu", ulValue );
@@ -432,8 +427,24 @@ void V_StripExtension( std::string &in )
 		// Which would otherwise wind up with "" and "c:\my@email", respectively.
 		if ( in.rfind( '\\' ) < test && in.rfind( '/' ) < test )
 		{
 			in.resize( test );
 		}
 	}
 }
 
+
+//-----------------------------------------------------------------------------
+// Purpose: Tokenizes a string into a vector of strings
+//-----------------------------------------------------------------------------
+std::vector<std::string> TokenizeString( const std::string & sString, char cToken )
+{
+	std::vector<std::string> vecStrings;
+	std::istringstream stream( sString );
+	std::string s;
+	while ( std::getline( stream, s, cToken ) )
+	{
+		vecStrings.push_back( s );
+	}
+	return vecStrings;
+}
+
--- a/gfx/vr/openvr/src/strtools_public.h
+++ b/gfx/vr/openvr/src/strtools_public.h
@@ -1,14 +1,15 @@
 //========= Copyright Valve Corporation ============//
 #pragma once
 
 #include <string>
 #include <stdint.h>
 #include <sys/types.h>
+#include <vector>
 
 /** returns true if the string has the prefix */
 bool StringHasPrefix( const std::string & sString, const std::string & sPrefix );
 bool StringHasPrefixCaseSensitive( const std::string & sString, const std::string & sPrefix );
 
 /** returns if the string has the suffix */
 bool StringHasSuffix( const std::string &sString, const std::string &sSuffix );
 bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string &sSuffix );
@@ -59,16 +60,17 @@ inline errno_t wcsncpy_s(wchar_t *strDes
 	return wcslcpy(strDest, strSource, numberOfElements);
 }
 
 inline errno_t strncpy_s(char *strDest, size_t numberOfElements, const char *strSource, size_t count)
 {
 	return strlcpy(strDest, strSource, numberOfElements);
 }
 */
+
 #endif
 
 #if defined( LINUX )
 // this implementation does not return whether or not the destination was 
 // truncated, but that is straightforward to fix if anybody actually needs the
 // return code. 
 #include "string.h"
 inline void wcsncpy_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count)
@@ -87,19 +89,16 @@ inline void strncpy_s(char *strDest, siz
 
 #if defined( _WIN32 ) && _MSC_VER < 1800
 inline uint64_t strtoull(const char *str, char **endptr, int base) { return _strtoui64( str, endptr, base ); }
 #endif
 
 /* Handles copying a std::string into a buffer as would be provided in an API */
 uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t unBufferLen );
 
-/* Handles copying a buffer into an std::string and auto adds null terminator */
-void BufferToStdString( std::string & sDest, const char *pchBuffer, uint32_t unBufferLen );
-
 /** Returns a std::string from a uint64_t */
 // std::string Uint64ToString( uint64_t ulValue );
 // Commented out by Mozilla, please see README.mozilla
 
 /** returns a uint64_t from a string */
 uint64_t StringToUint64( const std::string & sValue );
 
 //-----------------------------------------------------------------------------
@@ -122,8 +121,10 @@ void V_URLEncode( char *pchDest, int nDe
 size_t V_URLDecode( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen );
 
 //-----------------------------------------------------------------------------
 // Purpose: strip extension from a path
 //-----------------------------------------------------------------------------
 void V_StripExtension( std::string &in );
 
 
+/** Tokenizes a string into a vector of strings */
+std::vector<std::string> TokenizeString( const std::string & sString, char cToken );
--- a/gfx/vr/openvr/src/vrpathregistry_public.cpp
+++ b/gfx/vr/openvr/src/vrpathregistry_public.cpp
@@ -55,17 +55,17 @@ static std::string GetAppSettingsPath()
 		if ( [paths count] == 0 )
 		{
 			return "";
 		}
 		
 		NSString *resolvedPath = [paths objectAtIndex:0];
 		resolvedPath = [resolvedPath stringByAppendingPathComponent: @"OpenVR"];
 		
-		if ( ![[NSFileManager new] createDirectoryAtPath: resolvedPath withIntermediateDirectories:YES attributes:nil error:nil] )
+		if ( ![[NSFileManager defaultManager] createDirectoryAtPath: resolvedPath withIntermediateDirectories:YES attributes:nil error:nil] )
 		{
 			return "";
 		}
 		
 		sSettingsDir.assign( [resolvedPath UTF8String] );
 	}
 	return sSettingsDir;
 #elif defined( LINUX )