diff --git a/wineopenxr/make_openxr b/wineopenxr/make_openxr
index 58c20f77..bda7494c 100755
--- a/wineopenxr/make_openxr
+++ b/wineopenxr/make_openxr
@@ -164,12 +164,6 @@ FUNCTION_OVERRIDES = {
     "xrCreateSession" : {"dispatch" : True, "driver" : True, "thunk" : False},
     "xrDestroySession" : {"dispatch" : True, "driver" : True, "thunk" : False},
 
-    "xrCreateHandTrackerEXT" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrDestroyHandTrackerEXT" : {"dispatch" : True, "driver" : True, "thunk" : False},
-
-    "xrCreateSpatialAnchorMSFT" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrDestroySpatialAnchorMSFT" : {"dispatch" : True, "driver" : True, "thunk" : False},
-
     "xrGetInstanceProcAddr" : {"dispatch" : False, "driver" : True, "thunk" : False},
     "xrEnumerateInstanceExtensionProperties" : {"dispatch" : False, "driver" : True, "thunk" : False},
 
@@ -192,25 +186,6 @@ FUNCTION_OVERRIDES = {
     "xrCreateSwapchain" : {"dispatch" : True, "driver" : True, "thunk" : False},
     "xrDestroySwapchain" : {"dispatch" : True, "driver" : True, "thunk" : False},
     "xrEndFrame" : {"dispatch" : True, "driver" : True, "thunk" : False},
-
-    "xrCreateSceneObserverMSFT" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrDestroySceneObserverMSFT" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrCreateSceneMSFT" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrDestroySceneMSFT" : {"dispatch" : True, "driver" : True, "thunk" : False},
-
-    "xrCreateSpatialAnchorFromPersistedNameMSFT" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrCreateSpatialAnchorStoreConnectionMSFT" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrDestroySpatialAnchorStoreConnectionMSFT" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrCreateFoveationProfileFB" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrDestroyFoveationProfileFB" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrCreateGeometryInstanceFB" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrDestroyGeometryInstanceFB" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrCreateTriangleMeshFB" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrDestroyTriangleMeshFB" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrCreatePassthroughFB" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrDestroyPassthroughFB" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrCreatePassthroughLayerFB" : {"dispatch" : True, "driver" : True, "thunk" : False},
-    "xrDestroyPassthroughLayerFB" : {"dispatch" : True, "driver" : True, "thunk" : False},
 }
 
 STRUCT_CHAIN_CONVERSIONS = [
@@ -222,6 +197,35 @@ STRUCTS_PUT_FIRST = [
     "XrExtent3Df",
 ]
 
+AUTO_MAPPED_HANDLES = [
+    "XrSpace",
+    "XrSpatialAnchorMSFT",
+    "XrSpatialAnchorStoreConnectionMSFT",
+    "XrHandTrackerEXT",
+    "XrExportedLocalizationMapML",
+    "XrMarkerDetectorML",
+    "XrSceneMSFT",
+    "XrSceneObserverMSFT",
+    "XrSpatialGraphNodeBindingMSFT",
+    "XrFoveationProfileFB",
+    "XrTriangleMeshFB",
+    "XrPassthroughFB",
+    "XrPassthroughLayerFB",
+    "XrGeometryInstanceFB",
+    "XrEnvironmentDepthProviderMETA",
+    "XrVirtualKeyboardMETA",
+    "XrPlaneDetectorEXT",
+    "XrEyeTrackerFB",
+    "XrSpaceUserFB",
+    "XrBodyTrackerFB",
+    "XrFaceTrackerFB",
+    "XrFaceTracker2FB",
+    "XrEnvironmentDepthSwapchainMETA",
+    "XrPassthroughHTC",
+    "XrFacialTrackerHTC",
+    "XrPassthroughColorLutMETA",
+]
+
 class Direction(Enum):
     """ Parameter direction: input, output, input_output. """
     INPUT = 1
@@ -633,6 +637,8 @@ class XrFunction(object):
     def body(self):
         body = ""
 
+        if self.type != "void":
+            body += "    {0} ret;\n\n".format(self.type)
         if not self.needs_private_thunk():
             body += "    {0}".format(self.trace())
 
@@ -644,13 +650,23 @@ class XrFunction(object):
             if self.type == "void":
                 body += "    {0}({1});\n".format(self.name, params)
             else:
-                body += "    return {0}({1});\n".format(self.name, params)
+                body += "    ret = {0}({1});\n".format(self.name, params)
         else:
             if self.type == "void":
                 body += "    {0}.p_{1}({2});\n".format(self.params[0].dispatch_table(), self.name, params)
             else:
-                body += "    return {0}.p_{1}({2});\n".format(self.params[0].dispatch_table(), self.name, params)
+                body += "    ret = {0}.p_{1}({2});\n".format(self.params[0].dispatch_table(), self.name, params)
 
+        if "Destroy" in self.name:
+            for p in self.params:
+                if p.type in AUTO_MAPPED_HANDLES:
+                    body += "    unregister_dispatchable_handle((uint64_t){0});\n".format(p.name)
+        if "Create" in self.name:
+            for p in self.params:
+                if p.type in AUTO_MAPPED_HANDLES and p.is_pointer():
+                    body += "    if (!ret) register_dispatchable_handle((uint64_t)*{0}, &({1}));\n".format(p.name, self.params[0].dispatch_table())
+        if self.type != "void":
+            body += "    return ret;\n"
         return body
 
     def body_conversion(self):
@@ -883,8 +899,6 @@ class XrHandle(object):
             return "wine_session->wine_instance->funcs"
         if self.parent in ["XrActionSet"]:
             return "wine_action_set->wine_instance->funcs"
-        if self.parent in ["XrSceneObserverMSFT"]:
-            return "wine_scene_observer_msft->wine_session->wine_instance->funcs"
 
         LOGGER.error("Unhandled dispatchable parent: {0}".format(self.parent))
 
@@ -919,38 +933,19 @@ class XrHandle(object):
 
         native_handle_name = None
 
+        if self.name in AUTO_MAPPED_HANDLES:
+            return None
+
         if self.name == "XrInstance":
             native_handle_name = "instance"
         if self.name == "XrSession":
             native_handle_name = "session"
-        if self.name == "XrHandTrackerEXT":
-            native_handle_name = "hand_tracker"
-        if self.name == "XrSpatialAnchorMSFT":
-            native_handle_name = "spatial_anchor"
         if self.name == "XrSwapchain":
             native_handle_name = "swapchain"
         if self.name == "XrActionSet":
             return None
         if self.name == "XrAction":
             return None
-        if self.name == "XrSpace":
-            return None
-        if self.name == "XrGeometryInstanceFB":
-            native_handle_name = "instance"
-        if self.name == "XrPassthroughFB":
-            native_handle_name = "passthrough"
-        if self.name == "XrPassthroughLayerFB":
-            native_handle_name = "layer"
-        if self.name == "XrTriangleMeshFB":
-            native_handle_name = "mesh"
-        if self.name == "XrFoveationProfileFB":
-            native_handle_name = "foveation_profile"
-        if self.name == "XrSceneObserverMSFT":
-            native_handle_name = "scene_observer_msft"
-        if self.name == "XrSceneMSFT":
-            native_handle_name = "scene_msft"
-        if self.name == "XrSpatialAnchorStoreConnectionMSFT":
-            native_handle_name = "spatial_anchor_store_connection"
 
         if native_handle_name:
             return "((wine_{0} *){1})->{2}".format(self.name, name, native_handle_name)
@@ -1436,7 +1431,10 @@ class XrParam(object):
         if not self.is_dispatchable():
             return None
 
-        return "((wine_{0} *){1})->{2}".format(self.type, self.name, self.handle.dispatch_table())
+        if self.type in AUTO_MAPPED_HANDLES:
+            return "(*get_dispatch_table((uint64_t)({0})))".format(self.name)
+        else:
+            return "((wine_{0} *){1})->{2}".format(self.type, self.name, self.handle.dispatch_table())
 
     def format_string(self):
         return self.format_str
diff --git a/wineopenxr/openxr.c b/wineopenxr/openxr.c
index f53f7db4..7324a854 100644
--- a/wineopenxr/openxr.c
+++ b/wineopenxr/openxr.c
@@ -15,6 +15,8 @@
 #include "d3d11_3.h"
 #include "d3d12.h"
 
+#include "wine/rbtree.h"
+
 /* we want to use the native linux header */
 #pragma push_macro("_WIN32")
 #pragma push_macro("__cdecl")
@@ -83,6 +85,26 @@ static char *wineopenxr_strdup(const char *src)
     return r;
 }
 
+struct handle_instance_lookup_entry
+{
+    struct rb_entry entry;
+    uint64_t handle;
+    struct openxr_instance_funcs *funcs;
+};
+
+static struct rb_tree handle_instance_lookup;
+static SRWLOCK handle_instance_lookup_lock = SRWLOCK_INIT;
+static struct wine_XrInstance *last_instance;
+
+static int wrapper_entry_compare(const void *key, const struct rb_entry *entry)
+{
+    struct handle_instance_lookup_entry *wrapper = RB_ENTRY_VALUE(entry, struct handle_instance_lookup_entry, entry);
+    const uint64_t *handle = key;
+    if (*handle < wrapper->handle) return -1;
+    if (*handle > wrapper->handle) return 1;
+    return 0;
+}
+
 VkDevice(*get_native_VkDevice)(VkDevice);
 VkInstance(*get_native_VkInstance)(VkInstance);
 VkPhysicalDevice(*get_native_VkPhysicalDevice)(VkPhysicalDevice);
@@ -587,6 +609,7 @@ XrResult load_host_openxr_loader(void)
 
     load_vk_unwrappers();
 
+    rb_init(&handle_instance_lookup, wrapper_entry_compare);
     return XR_SUCCESS;
 }
 
@@ -825,6 +848,7 @@ XrResult WINAPI wine_xrCreateInstance(const XrInstanceCreateInfo *createInfo, Xr
 #undef USE_XR_FUNC
 
     *instance = (XrInstance)wine_instance;
+    last_instance = wine_instance;
 
 cleanup:
     for(i = 0; i < our_createInfo.enabledExtensionCount; ++i)
@@ -1037,486 +1061,6 @@ XrResult WINAPI wine_xrDestroySession(XrSession session)
     return XR_SUCCESS;
 }
 
-XrResult WINAPI wine_xrCreateHandTrackerEXT(XrSession session, const XrHandTrackerCreateInfoEXT *createInfo,
-        XrHandTrackerEXT *handTracker)
-{
-    wine_XrSession *wine_session = (wine_XrSession *)session;
-    wine_XrHandTrackerEXT *wine_handTracker;
-    XrResult res;
-
-    WINE_TRACE("%p, %p, %p\n", session, createInfo, handTracker);
-
-    wine_handTracker = heap_alloc_zero(sizeof(*wine_handTracker));
-
-    res = wine_session->wine_instance->funcs.p_xrCreateHandTrackerEXT(wine_session->session, createInfo, &wine_handTracker->hand_tracker);
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrCreateHandTrackerEXT failed: %d\n", res);
-        heap_free(wine_handTracker);
-        return res;
-    }
-
-    wine_handTracker->wine_session = wine_session;
-
-    *handTracker = (XrHandTrackerEXT)wine_handTracker;
-
-    WINE_TRACE("allocated wine handTracker %p for native handTracker %p\n",
-            wine_handTracker, wine_handTracker->hand_tracker);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrDestroyHandTrackerEXT(XrHandTrackerEXT handTracker)
-{
-    wine_XrHandTrackerEXT *wine_handTracker = (wine_XrHandTrackerEXT *)handTracker;
-    XrResult res;
-
-    WINE_TRACE("%p\n", handTracker);
-
-    res = wine_handTracker->wine_session->wine_instance->funcs.p_xrDestroyHandTrackerEXT(wine_handTracker->hand_tracker);
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrDestroyHandTrackerEXT failed: %d\n", res);
-        return res;
-    }
-
-    heap_free(wine_handTracker);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrCreateSpatialAnchorMSFT(XrSession session,
-        const XrSpatialAnchorCreateInfoMSFT *createInfo, XrSpatialAnchorMSFT *anchor)
-{
-    wine_XrSession *wine_session = (wine_XrSession *)session;
-    wine_XrSpatialAnchorMSFT *wine_anchor;
-    XrResult res;
-
-    WINE_TRACE("%p, %p, %p\n", session, createInfo, anchor);
-
-    wine_anchor = heap_alloc_zero(sizeof(*wine_anchor));
-
-    res = wine_session->wine_instance->funcs.p_xrCreateSpatialAnchorMSFT(wine_session->session, createInfo, &wine_anchor->spatial_anchor);
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrCreateSpatialAnchorMSFT failed: %d\n", res);
-        heap_free(wine_anchor);
-        return res;
-    }
-
-    wine_anchor->wine_session = wine_session;
-
-    *anchor = (XrSpatialAnchorMSFT)wine_anchor;
-
-    WINE_TRACE("allocated wine spatialAnchor %p for native spatialAnchor %p\n",
-            wine_anchor, wine_anchor->spatial_anchor);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrCreateSpatialAnchorFromPersistedNameMSFT(XrSession session,
-        const XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT *create_info,
-        XrSpatialAnchorMSFT *anchor)
-{
-    wine_XrSession *wine_session = (wine_XrSession *)session;
-    wine_XrSpatialAnchorMSFT *wine_anchor;
-    XrResult res;
-
-    WINE_TRACE("%p, %p, %p\n", session, create_info, anchor);
-
-    wine_anchor = heap_alloc_zero(sizeof(*wine_anchor));
-
-    res = wine_session->wine_instance->funcs.p_xrCreateSpatialAnchorFromPersistedNameMSFT(wine_session->session,
-            create_info, &wine_anchor->spatial_anchor);
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrCreateSpatialAnchorFromPersistedNameMSFT failed: %d\n", res);
-        heap_free(wine_anchor);
-        return res;
-    }
-
-    wine_anchor->wine_session = wine_session;
-
-    *anchor = (XrSpatialAnchorMSFT)wine_anchor;
-
-    WINE_TRACE("allocated wine spatialAnchor %p for native spatialAnchor %p\n",
-            wine_anchor, wine_anchor->spatial_anchor);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrDestroySpatialAnchorMSFT(XrSpatialAnchorMSFT anchor)
-{
-    wine_XrSpatialAnchorMSFT *wine_anchor = (wine_XrSpatialAnchorMSFT *)anchor;
-    XrResult res;
-
-    WINE_TRACE("%p\n", anchor);
-
-    res = wine_anchor->wine_session->wine_instance->funcs.p_xrDestroySpatialAnchorMSFT(wine_anchor->spatial_anchor);
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrDestroySpatialAnchorMSFT failed: %d\n", res);
-        return res;
-    }
-
-    heap_free(wine_anchor);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrCreateSpatialAnchorStoreConnectionMSFT(XrSession session, XrSpatialAnchorStoreConnectionMSFT *anchor_store)
-{
-    wine_XrSpatialAnchorStoreConnectionMSFT *wine_anchor_store;
-    wine_XrSession *wine_session = (wine_XrSession *)session;
-    XrResult res;
-
-    WINE_TRACE("%p, %p\n", session, anchor_store);
-
-    wine_anchor_store = heap_alloc_zero(sizeof(*wine_anchor_store));
-
-    res = wine_session->wine_instance->funcs.p_xrCreateSpatialAnchorStoreConnectionMSFT(wine_session->session,
-            &wine_anchor_store->spatial_anchor_store_connection);
-
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrCreateSpatialAnchorStoreConnectionMSFT failed: %d\n", res);
-        heap_free(wine_anchor_store);
-        return res;
-    }
-
-    wine_anchor_store->wine_session = wine_session;
-
-    *anchor_store = (XrSpatialAnchorStoreConnectionMSFT)wine_anchor_store;
-
-    WINE_TRACE("allocated wine_anchor_store %p for native spatial_anchor_store_connection %p\n",
-            wine_anchor_store, wine_anchor_store->spatial_anchor_store_connection);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrDestroySpatialAnchorStoreConnectionMSFT(XrSpatialAnchorStoreConnectionMSFT anchor_store)
-{
-    wine_XrSpatialAnchorStoreConnectionMSFT *wine_anchor_store
-            = (wine_XrSpatialAnchorStoreConnectionMSFT *)anchor_store;
-    XrResult res;
-
-    WINE_TRACE("%p\n", anchor_store);
-
-    res = wine_anchor_store->wine_session->wine_instance->funcs.p_xrDestroySpatialAnchorStoreConnectionMSFT
-            (wine_anchor_store->spatial_anchor_store_connection);
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrDestroySpatialAnchorStoreConnectionMSFT failed: %d\n", res);
-        return res;
-    }
-
-    heap_free(wine_anchor_store);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrCreateSceneObserverMSFT(XrSession session,
-        const XrSceneObserverCreateInfoMSFT *createInfo, XrSceneObserverMSFT *observer)
-{
-    wine_XrSession *wine_session = (wine_XrSession *)session;
-    wine_XrSceneObserverMSFT *wine_scene_observer_msft;
-    XrResult res;
-
-    WINE_TRACE("%p, %p, %p\n", session, createInfo, observer);
-
-    wine_scene_observer_msft = heap_alloc_zero(sizeof(*wine_scene_observer_msft));
-
-    res = wine_session->wine_instance->funcs.p_xrCreateSceneObserverMSFT(wine_session->session,
-            createInfo, &wine_scene_observer_msft->scene_observer_msft);
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrCreateSceneObserverMSFT failed: %d\n", res);
-        heap_free(wine_scene_observer_msft);
-        return res;
-    }
-
-    wine_scene_observer_msft->wine_session = wine_session;
-
-    *observer = (XrSceneObserverMSFT)wine_scene_observer_msft;
-
-    WINE_TRACE("allocated wine sceneObserver %p for native sceneObserver %p\n",
-            wine_scene_observer_msft, wine_scene_observer_msft->scene_observer_msft);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrDestroySceneObserverMSFT(XrSceneObserverMSFT observer)
-{
-    wine_XrSceneObserverMSFT *wine_observer = (wine_XrSceneObserverMSFT *)observer;
-    XrResult res;
-
-    WINE_TRACE("%p\n", observer);
-
-    res = wine_observer->wine_session->wine_instance->funcs.p_xrDestroySceneObserverMSFT(wine_observer->scene_observer_msft);
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrDestroySceneObserverMSFT failed: %d\n", res);
-        return res;
-    }
-
-    heap_free(wine_observer);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrCreateSceneMSFT(XrSceneObserverMSFT observer,
-        const XrSceneCreateInfoMSFT *createInfo, XrSceneMSFT *scene)
-{
-    wine_XrSceneObserverMSFT *wine_observer = (wine_XrSceneObserverMSFT *)observer;
-    wine_XrSceneMSFT *wine_scene_msft;
-    XrResult res;
-
-    WINE_TRACE("%p, %p, %p\n", observer, createInfo, scene);
-
-    wine_scene_msft = heap_alloc_zero(sizeof(*wine_scene_msft));
-
-    res = wine_observer->wine_session->wine_instance->funcs.p_xrCreateSceneMSFT(wine_observer->scene_observer_msft,
-            createInfo, &wine_scene_msft->scene_msft);
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrCreateSceneMSFT failed: %d\n", res);
-        heap_free(wine_scene_msft);
-        return res;
-    }
-
-    wine_scene_msft->wine_scene_observer_msft = wine_observer;
-
-    *scene = (XrSceneMSFT)wine_scene_msft;
-
-    WINE_TRACE("allocated wine sceneMSFT %p for native sceneMSFT %p\n",
-            wine_scene_msft, wine_scene_msft->scene_msft);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrDestroySceneMSFT(XrSceneMSFT scene)
-{
-    wine_XrSceneMSFT *wine_scene = (wine_XrSceneMSFT *)scene;
-    XrResult res;
-
-    WINE_TRACE("%p\n", scene);
-
-    res = wine_scene->wine_scene_observer_msft->wine_session->wine_instance->funcs.p_xrDestroySceneMSFT(wine_scene->scene_msft);
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrDestroySceneMSFT failed: %d\n", res);
-        return res;
-    }
-
-    heap_free(wine_scene);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrCreateFoveationProfileFB(XrSession session, const XrFoveationProfileCreateInfoFB *create_info,
-        XrFoveationProfileFB *profile)
-{
-    wine_XrSession *wine_session = (wine_XrSession *)session;
-    wine_XrFoveationProfileFB *wine_foveation_profile;
-    XrResult res;
-
-    WINE_TRACE("%p, %p\n", session, profile);
-
-    wine_foveation_profile = heap_alloc_zero(sizeof(*wine_foveation_profile));
-
-    res = wine_session->wine_instance->funcs.p_xrCreateFoveationProfileFB(wine_session->session, create_info,
-            &wine_foveation_profile->foveation_profile);
-
-    if(res != XR_SUCCESS){
-        WINE_WARN("xrCreateSpatialAnchorStoreConnectionMSFT failed: %d\n", res);
-        heap_free(wine_foveation_profile);
-        return res;
-    }
-
-    wine_foveation_profile->wine_session = wine_session;
-
-    *profile = (XrFoveationProfileFB)wine_foveation_profile;
-
-    WINE_TRACE("allocated wine_foveation_profile %p for native foveation_profile %p.\n",
-            wine_foveation_profile, wine_foveation_profile->foveation_profile);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrDestroyFoveationProfileFB(XrFoveationProfileFB profile)
-{
-    wine_XrFoveationProfileFB *wine_profile = (wine_XrFoveationProfileFB *)profile;
-    XrResult res;
-
-    WINE_TRACE("%p\n", profile);
-
-    res = wine_profile->wine_session->wine_instance->funcs.p_xrDestroyFoveationProfileFB(wine_profile->foveation_profile);
-    if(res != XR_SUCCESS){
-        WINE_WARN("rDestroyFoveationProfileFB failed: %d\n", res);
-        return res;
-    }
-
-    heap_free(wine_profile);
-
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrCreateGeometryInstanceFB(XrSession session, const XrGeometryInstanceCreateInfoFB *create_info,
-        XrGeometryInstanceFB *out)
-{
-    wine_XrSession *wine_session = (wine_XrSession *)session;
-    XrGeometryInstanceCreateInfoFB our_create_info;
-    wine_XrGeometryInstanceFB *wine_instance;
-    XrResult res;
-
-    WINE_TRACE("%p %p %p\n", session, create_info, out);
-
-    wine_instance = heap_alloc_zero(sizeof(*wine_instance));
-    our_create_info = *create_info;
-    our_create_info.layer = ((wine_XrPassthroughLayerFB *)create_info->layer)->layer;
-    our_create_info.mesh = ((wine_XrTriangleMeshFB *)create_info->mesh)->mesh;
-
-    res = wine_session->wine_instance->funcs.p_xrCreateGeometryInstanceFB(wine_session->session, &our_create_info,
-            &wine_instance->instance);
-    if(res != XR_SUCCESS)
-    {
-        WINE_WARN("Failed, res %d\n", res);
-        heap_free(wine_instance);
-        return res;
-    }
-    wine_instance->wine_session = wine_session;
-    *out = (XrGeometryInstanceFB)wine_instance;
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrDestroyGeometryInstanceFB(XrGeometryInstanceFB instance)
-{
-    wine_XrGeometryInstanceFB *wine_instance = (wine_XrGeometryInstanceFB *)instance;
-    XrResult res;
-
-    WINE_TRACE("%p\n", instance);
-
-    res = wine_instance->wine_session->wine_instance->funcs.p_xrDestroyGeometryInstanceFB(wine_instance->instance);
-    if(res != XR_SUCCESS){
-        WINE_WARN("Failed, res %d\n", res);
-        return res;
-    }
-    heap_free(wine_instance);
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrCreateTriangleMeshFB(XrSession session, const XrTriangleMeshCreateInfoFB *create_info,
-        XrTriangleMeshFB *out)
-{
-    wine_XrSession *wine_session = (wine_XrSession *)session;
-    wine_XrTriangleMeshFB *wine_mesh;
-    XrResult res;
-
-    WINE_TRACE("%p %p %p\n", session, create_info, out);
-
-    wine_mesh = heap_alloc_zero(sizeof(*wine_mesh));
-
-    res = wine_session->wine_instance->funcs.p_xrCreateTriangleMeshFB(wine_session->session, create_info,
-            &wine_mesh->mesh);
-    if(res != XR_SUCCESS)
-    {
-        WINE_WARN("Failed, res %d\n", res);
-        heap_free(wine_mesh);
-        return res;
-    }
-    wine_mesh->wine_session = wine_session;
-    *out = (XrTriangleMeshFB)wine_mesh;
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrDestroyTriangleMeshFB(XrTriangleMeshFB mesh)
-{
-    wine_XrTriangleMeshFB *wine_mesh = (wine_XrTriangleMeshFB *)mesh;
-    XrResult res;
-
-    WINE_TRACE("%p\n", mesh);
-
-    res = wine_mesh->wine_session->wine_instance->funcs.p_xrDestroyTriangleMeshFB(wine_mesh->mesh);
-    if(res != XR_SUCCESS){
-        WINE_WARN("Failed, res %d\n", res);
-        return res;
-    }
-    heap_free(wine_mesh);
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrCreatePassthroughFB(XrSession session, const XrPassthroughCreateInfoFB *create_info,
-        XrPassthroughFB *out)
-{
-    wine_XrSession *wine_session = (wine_XrSession *)session;
-    wine_XrPassthroughFB *wine_passthrough;
-    XrResult res;
-
-    WINE_TRACE("%p %p %p\n", session, create_info, out);
-
-    wine_passthrough = heap_alloc_zero(sizeof(*wine_passthrough));
-
-    res = wine_session->wine_instance->funcs.p_xrCreatePassthroughFB(wine_session->session, create_info,
-            &wine_passthrough->passthrough);
-    if(res != XR_SUCCESS)
-    {
-        WINE_WARN("Failed, res %d\n", res);
-        heap_free(wine_passthrough);
-        return res;
-    }
-    wine_passthrough->wine_session = wine_session;
-    *out = (XrPassthroughFB)wine_passthrough;
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrDestroyPassthroughFB(XrPassthroughFB passthrough)
-{
-    wine_XrPassthroughFB *wine_passthrough = (wine_XrPassthroughFB *)passthrough;
-    XrResult res;
-
-    WINE_TRACE("%p\n", passthrough);
-
-    res = wine_passthrough->wine_session->wine_instance->funcs.p_xrDestroyPassthroughFB(wine_passthrough->passthrough);
-    if(res != XR_SUCCESS){
-        WINE_WARN("Failed, res %d\n", res);
-        return res;
-    }
-    heap_free(wine_passthrough);
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrCreatePassthroughLayerFB(XrSession session, const XrPassthroughLayerCreateInfoFB *create_info,
-        XrPassthroughLayerFB *out)
-{
-    wine_XrSession *wine_session = (wine_XrSession *)session;
-    XrPassthroughLayerCreateInfoFB our_create_info;
-    wine_XrPassthroughLayerFB *wine_layer;
-    XrResult res;
-
-    WINE_TRACE("%p %p %p\n", session, create_info, out);
-
-    wine_layer = heap_alloc_zero(sizeof(*wine_layer));
-    our_create_info = *create_info;
-    our_create_info.passthrough = ((wine_XrPassthroughFB *)create_info->passthrough)->passthrough;
-
-    res = wine_session->wine_instance->funcs.p_xrCreatePassthroughLayerFB(wine_session->session, &our_create_info,
-            &wine_layer->layer);
-    if(res != XR_SUCCESS)
-    {
-        WINE_WARN("Failed, res %d\n", res);
-        heap_free(wine_layer);
-        return res;
-    }
-    wine_layer->wine_session = wine_session;
-    *out = (XrPassthroughLayerFB)wine_layer;
-    return XR_SUCCESS;
-}
-
-XrResult WINAPI wine_xrDestroyPassthroughLayerFB(XrPassthroughLayerFB layer)
-{
-    wine_XrPassthroughLayerFB *wine_layer = (wine_XrPassthroughLayerFB *)layer;
-    XrResult res;
-
-    WINE_TRACE("%p\n", layer);
-
-    res = wine_layer->wine_session->wine_instance->funcs.p_xrDestroyPassthroughLayerFB(wine_layer->layer);
-    if(res != XR_SUCCESS){
-        WINE_WARN("Failed, res %d\n", res);
-        return res;
-    }
-    heap_free(wine_layer);
-    return XR_SUCCESS;
-}
-
 XrResult WINAPI wine_xrNegotiateLoaderRuntimeInterface(
         const XrNegotiateLoaderInfo_win *loaderInfo,
         XrNegotiateRuntimeRequest_win *runtimeRequest)
@@ -2347,3 +1891,47 @@ XrResult WINAPI __wineopenxr_GetVulkanDeviceExtensions(uint32_t buflen, uint32_t
 
     return XR_SUCCESS;
 }
+
+void register_dispatchable_handle(uint64_t handle, struct openxr_instance_funcs *funcs)
+{
+    struct handle_instance_lookup_entry *entry;
+
+    entry = heap_alloc_zero(sizeof(*entry));
+    entry->handle = handle;
+    entry->funcs = funcs;
+    AcquireSRWLockExclusive(&handle_instance_lookup_lock);
+    rb_put(&handle_instance_lookup, &handle, &entry->entry);
+    ReleaseSRWLockExclusive(&handle_instance_lookup_lock);
+}
+
+void unregister_dispatchable_handle(uint64_t handle)
+{
+    struct rb_entry *entry;
+
+    AcquireSRWLockExclusive(&handle_instance_lookup_lock);
+    if ((entry = rb_get(&handle_instance_lookup, &handle)))
+        rb_remove(&handle_instance_lookup, entry);
+    ReleaseSRWLockExclusive(&handle_instance_lookup_lock);
+    if (entry)
+        heap_free(entry);
+    else
+        WINE_ERR("handle %s not found.\n", wine_dbgstr_longlong(handle));
+}
+
+struct openxr_instance_funcs *get_dispatch_table(uint64_t handle)
+{
+    struct openxr_instance_funcs *funcs = NULL;
+    struct rb_entry *entry;
+
+    AcquireSRWLockExclusive(&handle_instance_lookup_lock);
+    if ((entry = rb_get(&handle_instance_lookup, &handle)))
+        funcs = RB_ENTRY_VALUE(entry, struct handle_instance_lookup_entry, entry)->funcs;
+    ReleaseSRWLockExclusive(&handle_instance_lookup_lock);
+
+    if (!funcs)
+    {
+        WINE_ERR("handle %s not found.\n", wine_dbgstr_longlong(handle));
+        funcs = &last_instance->funcs;
+    }
+    return funcs;
+}
diff --git a/wineopenxr/openxr_private.h b/wineopenxr/openxr_private.h
index 02adafcd..7f1b7411 100644
--- a/wineopenxr/openxr_private.h
+++ b/wineopenxr/openxr_private.h
@@ -47,56 +47,6 @@ typedef struct wine_XrSession {
     view_info *view_infos;
 } wine_XrSession;
 
-typedef struct wine_XrHandTrackerEXT {
-    XrHandTrackerEXT hand_tracker;
-    struct wine_XrSession *wine_session;
-} wine_XrHandTrackerEXT;
-
-typedef struct wine_XrSpatialAnchorMSFT {
-    XrSpatialAnchorMSFT spatial_anchor;
-    struct wine_XrSession *wine_session;
-} wine_XrSpatialAnchorMSFT;
-
-typedef struct XrSpatialAnchorStoreConnectionMSFT {
-    XrSpatialAnchorStoreConnectionMSFT spatial_anchor_store_connection;
-    struct wine_XrSession *wine_session;
-} wine_XrSpatialAnchorStoreConnectionMSFT;
-
-typedef struct wine_XrSceneObserverMSFT {
-    XrSceneObserverMSFT scene_observer_msft;
-    struct wine_XrSession *wine_session;
-} wine_XrSceneObserverMSFT;
-
-typedef struct wine_XrSceneMSFT {
-    XrSceneMSFT scene_msft;
-    struct wine_XrSceneObserverMSFT *wine_scene_observer_msft;
-} wine_XrSceneMSFT;
-
-typedef struct wine_XrPassthroughFB {
-    XrPassthroughFB passthrough;
-    struct wine_XrSession *wine_session;
-} wine_XrPassthroughFB;
-
-typedef struct wine_XrPassthroughLayerFB {
-    XrPassthroughLayerFB layer;
-    struct wine_XrSession *wine_session;
-} wine_XrPassthroughLayerFB;
-
-typedef struct wine_XrTriangleMeshFB {
-    XrTriangleMeshFB mesh;
-    struct wine_XrSession *wine_session;
-} wine_XrTriangleMeshFB;
-
-typedef struct wine_XrGeometryInstanceFB {
-    XrGeometryInstanceFB instance;
-    struct wine_XrSession *wine_session;
-} wine_XrGeometryInstanceFB;
-
-typedef struct wine_XrFoveationProfileFB {
-    XrFoveationProfileFB foveation_profile;
-    struct wine_XrSession *wine_session;
-} wine_XrFoveationProfileFB;
-
 typedef struct wine_XrSwapchain{
     XrSwapchain swapchain;
     struct wine_XrSession *wine_session;
@@ -128,3 +78,7 @@ extern VkPhysicalDevice (*get_native_VkPhysicalDevice)(VkPhysicalDevice);
 extern VkPhysicalDevice (*get_wrapped_VkPhysicalDevice)(VkInstance, VkPhysicalDevice);
 extern VkQueue (*get_native_VkQueue)(VkQueue);
 extern XrResult load_host_openxr_loader(void);
+
+extern void register_dispatchable_handle(uint64_t handle, struct openxr_instance_funcs *funcs);
+extern void unregister_dispatchable_handle(uint64_t handle);
+extern struct openxr_instance_funcs *get_dispatch_table(uint64_t handle);
diff --git a/wineopenxr/openxr_thunks.c b/wineopenxr/openxr_thunks.c
index eaae533c..b8aaf94f 100644
--- a/wineopenxr/openxr_thunks.c
+++ b/wineopenxr/openxr_thunks.c
@@ -79,344 +79,729 @@ void free_XrInstanceCreateInfo_struct_chain(XrInstanceCreateInfo *s)
 
 XrResult WINAPI wine_xrAcquireSwapchainImage(XrSwapchain swapchain, const XrSwapchainImageAcquireInfo *acquireInfo, uint32_t *index)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", swapchain, acquireInfo, index);
-    return xrAcquireSwapchainImage(((wine_XrSwapchain *)swapchain)->swapchain, acquireInfo, index);
+    ret = xrAcquireSwapchainImage(((wine_XrSwapchain *)swapchain)->swapchain, acquireInfo, index);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrApplyForceFeedbackCurlMNDX(XrHandTrackerEXT handTracker, const XrForceFeedbackCurlApplyLocationsMNDX *locations)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", handTracker, locations);
-    return ((wine_XrHandTrackerEXT *)handTracker)->wine_session->wine_instance->funcs.p_xrApplyForceFeedbackCurlMNDX(((wine_XrHandTrackerEXT *)handTracker)->hand_tracker, locations);
+    ret = (*get_dispatch_table((uint64_t)(handTracker))).p_xrApplyForceFeedbackCurlMNDX(handTracker, locations);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrApplyFoveationHTC(XrSession session, const XrFoveationApplyInfoHTC *applyInfo)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", session, applyInfo);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrApplyFoveationHTC(((wine_XrSession *)session)->session, applyInfo);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrApplyFoveationHTC(((wine_XrSession *)session)->session, applyInfo);
+    return ret;
 }
 
 XrResult WINAPI wine_xrApplyHapticFeedback(XrSession session, const XrHapticActionInfo *hapticActionInfo, const XrHapticBaseHeader *hapticFeedback)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, hapticActionInfo, hapticFeedback);
-    return xrApplyHapticFeedback(((wine_XrSession *)session)->session, hapticActionInfo, hapticFeedback);
+    ret = xrApplyHapticFeedback(((wine_XrSession *)session)->session, hapticActionInfo, hapticFeedback);
+    return ret;
 }
 
 XrResult WINAPI wine_xrAttachSessionActionSets(XrSession session, const XrSessionActionSetsAttachInfo *attachInfo)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", session, attachInfo);
-    return xrAttachSessionActionSets(((wine_XrSession *)session)->session, attachInfo);
+    ret = xrAttachSessionActionSets(((wine_XrSession *)session)->session, attachInfo);
+    return ret;
 }
 
 XrResult WINAPI wine_xrBeginFrame(XrSession session, const XrFrameBeginInfo *frameBeginInfo)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", session, frameBeginInfo);
-    return xrBeginFrame(((wine_XrSession *)session)->session, frameBeginInfo);
+    ret = xrBeginFrame(((wine_XrSession *)session)->session, frameBeginInfo);
+    return ret;
 }
 
 XrResult WINAPI wine_xrBeginSession(XrSession session, const XrSessionBeginInfo *beginInfo)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", session, beginInfo);
-    return xrBeginSession(((wine_XrSession *)session)->session, beginInfo);
+    ret = xrBeginSession(((wine_XrSession *)session)->session, beginInfo);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrClearSpatialAnchorStoreMSFT(XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", spatialAnchorStore);
-    return ((wine_XrSpatialAnchorStoreConnectionMSFT *)spatialAnchorStore)->wine_session->wine_instance->funcs.p_xrClearSpatialAnchorStoreMSFT(((wine_XrSpatialAnchorStoreConnectionMSFT *)spatialAnchorStore)->spatial_anchor_store_connection);
+    ret = (*get_dispatch_table((uint64_t)(spatialAnchorStore))).p_xrClearSpatialAnchorStoreMSFT(spatialAnchorStore);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrComputeNewSceneMSFT(XrSceneObserverMSFT sceneObserver, const XrNewSceneComputeInfoMSFT *computeInfo)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", sceneObserver, computeInfo);
-    return ((wine_XrSceneObserverMSFT *)sceneObserver)->wine_session->wine_instance->funcs.p_xrComputeNewSceneMSFT(((wine_XrSceneObserverMSFT *)sceneObserver)->scene_observer_msft, computeInfo);
+    ret = (*get_dispatch_table((uint64_t)(sceneObserver))).p_xrComputeNewSceneMSFT(sceneObserver, computeInfo);
+    return ret;
 }
 
 XrResult WINAPI wine_xrCreateAction(XrActionSet actionSet, const XrActionCreateInfo *createInfo, XrAction *action)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", actionSet, createInfo, action);
-    return xrCreateAction(actionSet, createInfo, action);
+    ret = xrCreateAction(actionSet, createInfo, action);
+    return ret;
 }
 
 XrResult WINAPI wine_xrCreateActionSet(XrInstance instance, const XrActionSetCreateInfo *createInfo, XrActionSet *actionSet)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", instance, createInfo, actionSet);
-    return xrCreateActionSet(((wine_XrInstance *)instance)->instance, createInfo, actionSet);
+    ret = xrCreateActionSet(((wine_XrInstance *)instance)->instance, createInfo, actionSet);
+    return ret;
 }
 
 XrResult WINAPI wine_xrCreateActionSpace(XrSession session, const XrActionSpaceCreateInfo *createInfo, XrSpace *space)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, createInfo, space);
-    return xrCreateActionSpace(((wine_XrSession *)session)->session, createInfo, space);
+    ret = xrCreateActionSpace(((wine_XrSession *)session)->session, createInfo, space);
+    if (!ret) register_dispatchable_handle((uint64_t)*space, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
+}
+
+static XrResult WINAPI wine_xrCreateFoveationProfileFB(XrSession session, const XrFoveationProfileCreateInfoFB *createInfo, XrFoveationProfileFB *profile)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p, %p, %p\n", session, createInfo, profile);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreateFoveationProfileFB(((wine_XrSession *)session)->session, createInfo, profile);
+    if (!ret) register_dispatchable_handle((uint64_t)*profile, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
+}
+
+static XrResult WINAPI wine_xrCreateGeometryInstanceFB(XrSession session, const XrGeometryInstanceCreateInfoFB *createInfo, XrGeometryInstanceFB *outGeometryInstance)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p, %p, %p\n", session, createInfo, outGeometryInstance);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreateGeometryInstanceFB(((wine_XrSession *)session)->session, createInfo, outGeometryInstance);
+    if (!ret) register_dispatchable_handle((uint64_t)*outGeometryInstance, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
+}
+
+static XrResult WINAPI wine_xrCreateHandTrackerEXT(XrSession session, const XrHandTrackerCreateInfoEXT *createInfo, XrHandTrackerEXT *handTracker)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p, %p, %p\n", session, createInfo, handTracker);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreateHandTrackerEXT(((wine_XrSession *)session)->session, createInfo, handTracker);
+    if (!ret) register_dispatchable_handle((uint64_t)*handTracker, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
+}
+
+static XrResult WINAPI wine_xrCreatePassthroughFB(XrSession session, const XrPassthroughCreateInfoFB *createInfo, XrPassthroughFB *outPassthrough)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p, %p, %p\n", session, createInfo, outPassthrough);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreatePassthroughFB(((wine_XrSession *)session)->session, createInfo, outPassthrough);
+    if (!ret) register_dispatchable_handle((uint64_t)*outPassthrough, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
+}
+
+static XrResult WINAPI wine_xrCreatePassthroughLayerFB(XrSession session, const XrPassthroughLayerCreateInfoFB *createInfo, XrPassthroughLayerFB *outLayer)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p, %p, %p\n", session, createInfo, outLayer);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreatePassthroughLayerFB(((wine_XrSession *)session)->session, createInfo, outLayer);
+    if (!ret) register_dispatchable_handle((uint64_t)*outLayer, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
 }
 
 XrResult WINAPI wine_xrCreateReferenceSpace(XrSession session, const XrReferenceSpaceCreateInfo *createInfo, XrSpace *space)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, createInfo, space);
-    return xrCreateReferenceSpace(((wine_XrSession *)session)->session, createInfo, space);
+    ret = xrCreateReferenceSpace(((wine_XrSession *)session)->session, createInfo, space);
+    if (!ret) register_dispatchable_handle((uint64_t)*space, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
+}
+
+static XrResult WINAPI wine_xrCreateSceneMSFT(XrSceneObserverMSFT sceneObserver, const XrSceneCreateInfoMSFT *createInfo, XrSceneMSFT *scene)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p, %p, %p\n", sceneObserver, createInfo, scene);
+    ret = (*get_dispatch_table((uint64_t)(sceneObserver))).p_xrCreateSceneMSFT(sceneObserver, createInfo, scene);
+    if (!ret) register_dispatchable_handle((uint64_t)*scene, &((*get_dispatch_table((uint64_t)(sceneObserver)))));
+    return ret;
+}
+
+static XrResult WINAPI wine_xrCreateSceneObserverMSFT(XrSession session, const XrSceneObserverCreateInfoMSFT *createInfo, XrSceneObserverMSFT *sceneObserver)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p, %p, %p\n", session, createInfo, sceneObserver);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreateSceneObserverMSFT(((wine_XrSession *)session)->session, createInfo, sceneObserver);
+    if (!ret) register_dispatchable_handle((uint64_t)*sceneObserver, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
+}
+
+static XrResult WINAPI wine_xrCreateSpatialAnchorFromPersistedNameMSFT(XrSession session, const XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT *spatialAnchorCreateInfo, XrSpatialAnchorMSFT *spatialAnchor)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p, %p, %p\n", session, spatialAnchorCreateInfo, spatialAnchor);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreateSpatialAnchorFromPersistedNameMSFT(((wine_XrSession *)session)->session, spatialAnchorCreateInfo, spatialAnchor);
+    if (!ret) register_dispatchable_handle((uint64_t)*spatialAnchor, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
+}
+
+static XrResult WINAPI wine_xrCreateSpatialAnchorMSFT(XrSession session, const XrSpatialAnchorCreateInfoMSFT *createInfo, XrSpatialAnchorMSFT *anchor)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p, %p, %p\n", session, createInfo, anchor);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreateSpatialAnchorMSFT(((wine_XrSession *)session)->session, createInfo, anchor);
+    if (!ret) register_dispatchable_handle((uint64_t)*anchor, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
 }
 
 static XrResult WINAPI wine_xrCreateSpatialAnchorSpaceMSFT(XrSession session, const XrSpatialAnchorSpaceCreateInfoMSFT *createInfo, XrSpace *space)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, createInfo, space);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreateSpatialAnchorSpaceMSFT(((wine_XrSession *)session)->session, createInfo, space);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreateSpatialAnchorSpaceMSFT(((wine_XrSession *)session)->session, createInfo, space);
+    if (!ret) register_dispatchable_handle((uint64_t)*space, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
+}
+
+static XrResult WINAPI wine_xrCreateSpatialAnchorStoreConnectionMSFT(XrSession session, XrSpatialAnchorStoreConnectionMSFT *spatialAnchorStore)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p, %p\n", session, spatialAnchorStore);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreateSpatialAnchorStoreConnectionMSFT(((wine_XrSession *)session)->session, spatialAnchorStore);
+    if (!ret) register_dispatchable_handle((uint64_t)*spatialAnchorStore, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
+}
+
+static XrResult WINAPI wine_xrCreateTriangleMeshFB(XrSession session, const XrTriangleMeshCreateInfoFB *createInfo, XrTriangleMeshFB *outTriangleMesh)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p, %p, %p\n", session, createInfo, outTriangleMesh);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrCreateTriangleMeshFB(((wine_XrSession *)session)->session, createInfo, outTriangleMesh);
+    if (!ret) register_dispatchable_handle((uint64_t)*outTriangleMesh, &(((wine_XrSession *)session)->wine_instance->funcs));
+    return ret;
 }
 
 static XrResult WINAPI wine_xrDeserializeSceneMSFT(XrSceneObserverMSFT sceneObserver, const XrSceneDeserializeInfoMSFT *deserializeInfo)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", sceneObserver, deserializeInfo);
-    return ((wine_XrSceneObserverMSFT *)sceneObserver)->wine_session->wine_instance->funcs.p_xrDeserializeSceneMSFT(((wine_XrSceneObserverMSFT *)sceneObserver)->scene_observer_msft, deserializeInfo);
+    ret = (*get_dispatch_table((uint64_t)(sceneObserver))).p_xrDeserializeSceneMSFT(sceneObserver, deserializeInfo);
+    return ret;
 }
 
 XrResult WINAPI wine_xrDestroyAction(XrAction action)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", action);
-    return xrDestroyAction(action);
+    ret = xrDestroyAction(action);
+    return ret;
 }
 
 XrResult WINAPI wine_xrDestroyActionSet(XrActionSet actionSet)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", actionSet);
-    return xrDestroyActionSet(actionSet);
+    ret = xrDestroyActionSet(actionSet);
+    return ret;
+}
+
+static XrResult WINAPI wine_xrDestroyFoveationProfileFB(XrFoveationProfileFB profile)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p\n", profile);
+    ret = (*get_dispatch_table((uint64_t)(profile))).p_xrDestroyFoveationProfileFB(profile);
+    unregister_dispatchable_handle((uint64_t)profile);
+    return ret;
+}
+
+static XrResult WINAPI wine_xrDestroyGeometryInstanceFB(XrGeometryInstanceFB instance)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p\n", instance);
+    ret = (*get_dispatch_table((uint64_t)(instance))).p_xrDestroyGeometryInstanceFB(instance);
+    unregister_dispatchable_handle((uint64_t)instance);
+    return ret;
+}
+
+static XrResult WINAPI wine_xrDestroyHandTrackerEXT(XrHandTrackerEXT handTracker)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p\n", handTracker);
+    ret = (*get_dispatch_table((uint64_t)(handTracker))).p_xrDestroyHandTrackerEXT(handTracker);
+    unregister_dispatchable_handle((uint64_t)handTracker);
+    return ret;
+}
+
+static XrResult WINAPI wine_xrDestroyPassthroughFB(XrPassthroughFB passthrough)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p\n", passthrough);
+    ret = (*get_dispatch_table((uint64_t)(passthrough))).p_xrDestroyPassthroughFB(passthrough);
+    unregister_dispatchable_handle((uint64_t)passthrough);
+    return ret;
+}
+
+static XrResult WINAPI wine_xrDestroyPassthroughLayerFB(XrPassthroughLayerFB layer)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p\n", layer);
+    ret = (*get_dispatch_table((uint64_t)(layer))).p_xrDestroyPassthroughLayerFB(layer);
+    unregister_dispatchable_handle((uint64_t)layer);
+    return ret;
+}
+
+static XrResult WINAPI wine_xrDestroySceneMSFT(XrSceneMSFT scene)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p\n", scene);
+    ret = (*get_dispatch_table((uint64_t)(scene))).p_xrDestroySceneMSFT(scene);
+    unregister_dispatchable_handle((uint64_t)scene);
+    return ret;
+}
+
+static XrResult WINAPI wine_xrDestroySceneObserverMSFT(XrSceneObserverMSFT sceneObserver)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p\n", sceneObserver);
+    ret = (*get_dispatch_table((uint64_t)(sceneObserver))).p_xrDestroySceneObserverMSFT(sceneObserver);
+    unregister_dispatchable_handle((uint64_t)sceneObserver);
+    return ret;
 }
 
 XrResult WINAPI wine_xrDestroySpace(XrSpace space)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", space);
-    return xrDestroySpace(space);
+    ret = xrDestroySpace(space);
+    unregister_dispatchable_handle((uint64_t)space);
+    return ret;
+}
+
+static XrResult WINAPI wine_xrDestroySpatialAnchorMSFT(XrSpatialAnchorMSFT anchor)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p\n", anchor);
+    ret = (*get_dispatch_table((uint64_t)(anchor))).p_xrDestroySpatialAnchorMSFT(anchor);
+    unregister_dispatchable_handle((uint64_t)anchor);
+    return ret;
+}
+
+static XrResult WINAPI wine_xrDestroySpatialAnchorStoreConnectionMSFT(XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p\n", spatialAnchorStore);
+    ret = (*get_dispatch_table((uint64_t)(spatialAnchorStore))).p_xrDestroySpatialAnchorStoreConnectionMSFT(spatialAnchorStore);
+    unregister_dispatchable_handle((uint64_t)spatialAnchorStore);
+    return ret;
+}
+
+static XrResult WINAPI wine_xrDestroyTriangleMeshFB(XrTriangleMeshFB mesh)
+{
+    XrResult ret;
+
+    WINE_TRACE("%p\n", mesh);
+    ret = (*get_dispatch_table((uint64_t)(mesh))).p_xrDestroyTriangleMeshFB(mesh);
+    unregister_dispatchable_handle((uint64_t)mesh);
+    return ret;
 }
 
 XrResult WINAPI wine_xrEndSession(XrSession session)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", session);
-    return xrEndSession(((wine_XrSession *)session)->session);
+    ret = xrEndSession(((wine_XrSession *)session)->session);
+    return ret;
 }
 
 XrResult WINAPI wine_xrEnumerateApiLayerProperties(uint32_t propertyCapacityInput, uint32_t *propertyCountOutput, XrApiLayerProperties *properties)
 {
+    XrResult ret;
+
     WINE_TRACE("%u, %p, %p\n", propertyCapacityInput, propertyCountOutput, properties);
-    return xrEnumerateApiLayerProperties(propertyCapacityInput, propertyCountOutput, properties);
+    ret = xrEnumerateApiLayerProperties(propertyCapacityInput, propertyCountOutput, properties);
+    return ret;
 }
 
 XrResult WINAPI wine_xrEnumerateBoundSourcesForAction(XrSession session, const XrBoundSourcesForActionEnumerateInfo *enumerateInfo, uint32_t sourceCapacityInput, uint32_t *sourceCountOutput, XrPath *sources)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %u, %p, %p\n", session, enumerateInfo, sourceCapacityInput, sourceCountOutput, sources);
-    return xrEnumerateBoundSourcesForAction(((wine_XrSession *)session)->session, enumerateInfo, sourceCapacityInput, sourceCountOutput, sources);
+    ret = xrEnumerateBoundSourcesForAction(((wine_XrSession *)session)->session, enumerateInfo, sourceCapacityInput, sourceCountOutput, sources);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrEnumerateColorSpacesFB(XrSession session, uint32_t colorSpaceCapacityInput, uint32_t *colorSpaceCountOutput, XrColorSpaceFB *colorSpaces)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %u, %p, %p\n", session, colorSpaceCapacityInput, colorSpaceCountOutput, colorSpaces);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrEnumerateColorSpacesFB(((wine_XrSession *)session)->session, colorSpaceCapacityInput, colorSpaceCountOutput, colorSpaces);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrEnumerateColorSpacesFB(((wine_XrSession *)session)->session, colorSpaceCapacityInput, colorSpaceCountOutput, colorSpaces);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrEnumerateDisplayRefreshRatesFB(XrSession session, uint32_t displayRefreshRateCapacityInput, uint32_t *displayRefreshRateCountOutput, float *displayRefreshRates)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %u, %p, %p\n", session, displayRefreshRateCapacityInput, displayRefreshRateCountOutput, displayRefreshRates);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrEnumerateDisplayRefreshRatesFB(((wine_XrSession *)session)->session, displayRefreshRateCapacityInput, displayRefreshRateCountOutput, displayRefreshRates);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrEnumerateDisplayRefreshRatesFB(((wine_XrSession *)session)->session, displayRefreshRateCapacityInput, displayRefreshRateCountOutput, displayRefreshRates);
+    return ret;
 }
 
 XrResult WINAPI wine_xrEnumerateEnvironmentBlendModes(XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, uint32_t environmentBlendModeCapacityInput, uint32_t *environmentBlendModeCountOutput, XrEnvironmentBlendMode *environmentBlendModes)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %#x, %u, %p, %p\n", instance, wine_dbgstr_longlong(systemId), viewConfigurationType, environmentBlendModeCapacityInput, environmentBlendModeCountOutput, environmentBlendModes);
-    return xrEnumerateEnvironmentBlendModes(((wine_XrInstance *)instance)->instance, systemId, viewConfigurationType, environmentBlendModeCapacityInput, environmentBlendModeCountOutput, environmentBlendModes);
+    ret = xrEnumerateEnvironmentBlendModes(((wine_XrInstance *)instance)->instance, systemId, viewConfigurationType, environmentBlendModeCapacityInput, environmentBlendModeCountOutput, environmentBlendModes);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrEnumerateExternalCamerasOCULUS(XrSession session, uint32_t cameraCapacityInput, uint32_t *cameraCountOutput, XrExternalCameraOCULUS *cameras)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %u, %p, %p\n", session, cameraCapacityInput, cameraCountOutput, cameras);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrEnumerateExternalCamerasOCULUS(((wine_XrSession *)session)->session, cameraCapacityInput, cameraCountOutput, cameras);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrEnumerateExternalCamerasOCULUS(((wine_XrSession *)session)->session, cameraCapacityInput, cameraCountOutput, cameras);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrEnumeratePerformanceMetricsCounterPathsMETA(XrInstance instance, uint32_t counterPathCapacityInput, uint32_t *counterPathCountOutput, XrPath *counterPaths)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %u, %p, %p\n", instance, counterPathCapacityInput, counterPathCountOutput, counterPaths);
-    return ((wine_XrInstance *)instance)->funcs.p_xrEnumeratePerformanceMetricsCounterPathsMETA(((wine_XrInstance *)instance)->instance, counterPathCapacityInput, counterPathCountOutput, counterPaths);
+    ret = ((wine_XrInstance *)instance)->funcs.p_xrEnumeratePerformanceMetricsCounterPathsMETA(((wine_XrInstance *)instance)->instance, counterPathCapacityInput, counterPathCountOutput, counterPaths);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrEnumeratePersistedSpatialAnchorNamesMSFT(XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore, uint32_t spatialAnchorNamesCapacityInput, uint32_t *spatialAnchorNamesCountOutput, XrSpatialAnchorPersistenceNameMSFT *persistedAnchorNames)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %u, %p, %p\n", spatialAnchorStore, spatialAnchorNamesCapacityInput, spatialAnchorNamesCountOutput, persistedAnchorNames);
-    return ((wine_XrSpatialAnchorStoreConnectionMSFT *)spatialAnchorStore)->wine_session->wine_instance->funcs.p_xrEnumeratePersistedSpatialAnchorNamesMSFT(((wine_XrSpatialAnchorStoreConnectionMSFT *)spatialAnchorStore)->spatial_anchor_store_connection, spatialAnchorNamesCapacityInput, spatialAnchorNamesCountOutput, persistedAnchorNames);
+    ret = (*get_dispatch_table((uint64_t)(spatialAnchorStore))).p_xrEnumeratePersistedSpatialAnchorNamesMSFT(spatialAnchorStore, spatialAnchorNamesCapacityInput, spatialAnchorNamesCountOutput, persistedAnchorNames);
+    return ret;
 }
 
 XrResult WINAPI wine_xrEnumerateReferenceSpaces(XrSession session, uint32_t spaceCapacityInput, uint32_t *spaceCountOutput, XrReferenceSpaceType *spaces)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %u, %p, %p\n", session, spaceCapacityInput, spaceCountOutput, spaces);
-    return xrEnumerateReferenceSpaces(((wine_XrSession *)session)->session, spaceCapacityInput, spaceCountOutput, spaces);
+    ret = xrEnumerateReferenceSpaces(((wine_XrSession *)session)->session, spaceCapacityInput, spaceCountOutput, spaces);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrEnumerateRenderModelPathsFB(XrSession session, uint32_t pathCapacityInput, uint32_t *pathCountOutput, XrRenderModelPathInfoFB *paths)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %u, %p, %p\n", session, pathCapacityInput, pathCountOutput, paths);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrEnumerateRenderModelPathsFB(((wine_XrSession *)session)->session, pathCapacityInput, pathCountOutput, paths);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrEnumerateRenderModelPathsFB(((wine_XrSession *)session)->session, pathCapacityInput, pathCountOutput, paths);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrEnumerateReprojectionModesMSFT(XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, uint32_t modeCapacityInput, uint32_t *modeCountOutput, XrReprojectionModeMSFT *modes)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %#x, %u, %p, %p\n", instance, wine_dbgstr_longlong(systemId), viewConfigurationType, modeCapacityInput, modeCountOutput, modes);
-    return ((wine_XrInstance *)instance)->funcs.p_xrEnumerateReprojectionModesMSFT(((wine_XrInstance *)instance)->instance, systemId, viewConfigurationType, modeCapacityInput, modeCountOutput, modes);
+    ret = ((wine_XrInstance *)instance)->funcs.p_xrEnumerateReprojectionModesMSFT(((wine_XrInstance *)instance)->instance, systemId, viewConfigurationType, modeCapacityInput, modeCountOutput, modes);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrEnumerateSceneComputeFeaturesMSFT(XrInstance instance, XrSystemId systemId, uint32_t featureCapacityInput, uint32_t *featureCountOutput, XrSceneComputeFeatureMSFT *features)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %u, %p, %p\n", instance, wine_dbgstr_longlong(systemId), featureCapacityInput, featureCountOutput, features);
-    return ((wine_XrInstance *)instance)->funcs.p_xrEnumerateSceneComputeFeaturesMSFT(((wine_XrInstance *)instance)->instance, systemId, featureCapacityInput, featureCountOutput, features);
+    ret = ((wine_XrInstance *)instance)->funcs.p_xrEnumerateSceneComputeFeaturesMSFT(((wine_XrInstance *)instance)->instance, systemId, featureCapacityInput, featureCountOutput, features);
+    return ret;
 }
 
 XrResult WINAPI wine_xrEnumerateViewConfigurationViews(XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, uint32_t viewCapacityInput, uint32_t *viewCountOutput, XrViewConfigurationView *views)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %#x, %u, %p, %p\n", instance, wine_dbgstr_longlong(systemId), viewConfigurationType, viewCapacityInput, viewCountOutput, views);
-    return xrEnumerateViewConfigurationViews(((wine_XrInstance *)instance)->instance, systemId, viewConfigurationType, viewCapacityInput, viewCountOutput, views);
+    ret = xrEnumerateViewConfigurationViews(((wine_XrInstance *)instance)->instance, systemId, viewConfigurationType, viewCapacityInput, viewCountOutput, views);
+    return ret;
 }
 
 XrResult WINAPI wine_xrEnumerateViewConfigurations(XrInstance instance, XrSystemId systemId, uint32_t viewConfigurationTypeCapacityInput, uint32_t *viewConfigurationTypeCountOutput, XrViewConfigurationType *viewConfigurationTypes)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %u, %p, %p\n", instance, wine_dbgstr_longlong(systemId), viewConfigurationTypeCapacityInput, viewConfigurationTypeCountOutput, viewConfigurationTypes);
-    return xrEnumerateViewConfigurations(((wine_XrInstance *)instance)->instance, systemId, viewConfigurationTypeCapacityInput, viewConfigurationTypeCountOutput, viewConfigurationTypes);
+    ret = xrEnumerateViewConfigurations(((wine_XrInstance *)instance)->instance, systemId, viewConfigurationTypeCapacityInput, viewConfigurationTypeCountOutput, viewConfigurationTypes);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrEnumerateViveTrackerPathsHTCX(XrInstance instance, uint32_t pathCapacityInput, uint32_t *pathCountOutput, XrViveTrackerPathsHTCX *paths)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %u, %p, %p\n", instance, pathCapacityInput, pathCountOutput, paths);
-    return ((wine_XrInstance *)instance)->funcs.p_xrEnumerateViveTrackerPathsHTCX(((wine_XrInstance *)instance)->instance, pathCapacityInput, pathCountOutput, paths);
+    ret = ((wine_XrInstance *)instance)->funcs.p_xrEnumerateViveTrackerPathsHTCX(((wine_XrInstance *)instance)->instance, pathCapacityInput, pathCountOutput, paths);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGeometryInstanceSetTransformFB(XrGeometryInstanceFB instance, const XrGeometryInstanceTransformFB *transformation)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", instance, transformation);
-    return ((wine_XrGeometryInstanceFB *)instance)->wine_session->wine_instance->funcs.p_xrGeometryInstanceSetTransformFB(((wine_XrGeometryInstanceFB *)instance)->instance, transformation);
+    ret = (*get_dispatch_table((uint64_t)(instance))).p_xrGeometryInstanceSetTransformFB(instance, transformation);
+    return ret;
 }
 
 XrResult WINAPI wine_xrGetActionStateBoolean(XrSession session, const XrActionStateGetInfo *getInfo, XrActionStateBoolean *state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, getInfo, state);
-    return xrGetActionStateBoolean(((wine_XrSession *)session)->session, getInfo, state);
+    ret = xrGetActionStateBoolean(((wine_XrSession *)session)->session, getInfo, state);
+    return ret;
 }
 
 XrResult WINAPI wine_xrGetActionStateFloat(XrSession session, const XrActionStateGetInfo *getInfo, XrActionStateFloat *state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, getInfo, state);
-    return xrGetActionStateFloat(((wine_XrSession *)session)->session, getInfo, state);
+    ret = xrGetActionStateFloat(((wine_XrSession *)session)->session, getInfo, state);
+    return ret;
 }
 
 XrResult WINAPI wine_xrGetActionStatePose(XrSession session, const XrActionStateGetInfo *getInfo, XrActionStatePose *state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, getInfo, state);
-    return xrGetActionStatePose(((wine_XrSession *)session)->session, getInfo, state);
+    ret = xrGetActionStatePose(((wine_XrSession *)session)->session, getInfo, state);
+    return ret;
 }
 
 XrResult WINAPI wine_xrGetActionStateVector2f(XrSession session, const XrActionStateGetInfo *getInfo, XrActionStateVector2f *state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, getInfo, state);
-    return xrGetActionStateVector2f(((wine_XrSession *)session)->session, getInfo, state);
+    ret = xrGetActionStateVector2f(((wine_XrSession *)session)->session, getInfo, state);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetAudioInputDeviceGuidOculus(XrInstance instance, wchar_t buffer[])
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", instance, buffer);
-    return ((wine_XrInstance *)instance)->funcs.p_xrGetAudioInputDeviceGuidOculus(((wine_XrInstance *)instance)->instance, buffer);
+    ret = ((wine_XrInstance *)instance)->funcs.p_xrGetAudioInputDeviceGuidOculus(((wine_XrInstance *)instance)->instance, buffer);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetAudioOutputDeviceGuidOculus(XrInstance instance, wchar_t buffer[])
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", instance, buffer);
-    return ((wine_XrInstance *)instance)->funcs.p_xrGetAudioOutputDeviceGuidOculus(((wine_XrInstance *)instance)->instance, buffer);
+    ret = ((wine_XrInstance *)instance)->funcs.p_xrGetAudioOutputDeviceGuidOculus(((wine_XrInstance *)instance)->instance, buffer);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetControllerModelKeyMSFT(XrSession session, XrPath topLevelUserPath, XrControllerModelKeyStateMSFT *controllerModelKeyState)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %p\n", session, wine_dbgstr_longlong(topLevelUserPath), controllerModelKeyState);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetControllerModelKeyMSFT(((wine_XrSession *)session)->session, topLevelUserPath, controllerModelKeyState);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetControllerModelKeyMSFT(((wine_XrSession *)session)->session, topLevelUserPath, controllerModelKeyState);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetControllerModelPropertiesMSFT(XrSession session, XrControllerModelKeyMSFT modelKey, XrControllerModelPropertiesMSFT *properties)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %p\n", session, wine_dbgstr_longlong(modelKey), properties);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetControllerModelPropertiesMSFT(((wine_XrSession *)session)->session, modelKey, properties);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetControllerModelPropertiesMSFT(((wine_XrSession *)session)->session, modelKey, properties);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetControllerModelStateMSFT(XrSession session, XrControllerModelKeyMSFT modelKey, XrControllerModelStateMSFT *state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %p\n", session, wine_dbgstr_longlong(modelKey), state);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetControllerModelStateMSFT(((wine_XrSession *)session)->session, modelKey, state);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetControllerModelStateMSFT(((wine_XrSession *)session)->session, modelKey, state);
+    return ret;
 }
 
 XrResult WINAPI wine_xrGetCurrentInteractionProfile(XrSession session, XrPath topLevelUserPath, XrInteractionProfileState *interactionProfile)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %p\n", session, wine_dbgstr_longlong(topLevelUserPath), interactionProfile);
-    return xrGetCurrentInteractionProfile(((wine_XrSession *)session)->session, topLevelUserPath, interactionProfile);
+    ret = xrGetCurrentInteractionProfile(((wine_XrSession *)session)->session, topLevelUserPath, interactionProfile);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetDeviceSampleRateFB(XrSession session, const XrHapticActionInfo *hapticActionInfo, XrDevicePcmSampleRateGetInfoFB *deviceSampleRate)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, hapticActionInfo, deviceSampleRate);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetDeviceSampleRateFB(((wine_XrSession *)session)->session, hapticActionInfo, deviceSampleRate);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetDeviceSampleRateFB(((wine_XrSession *)session)->session, hapticActionInfo, deviceSampleRate);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetDisplayRefreshRateFB(XrSession session, float *displayRefreshRate)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", session, displayRefreshRate);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetDisplayRefreshRateFB(((wine_XrSession *)session)->session, displayRefreshRate);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetDisplayRefreshRateFB(((wine_XrSession *)session)->session, displayRefreshRate);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetFoveationEyeTrackedStateMETA(XrSession session, XrFoveationEyeTrackedStateMETA *foveationState)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", session, foveationState);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetFoveationEyeTrackedStateMETA(((wine_XrSession *)session)->session, foveationState);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetFoveationEyeTrackedStateMETA(((wine_XrSession *)session)->session, foveationState);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetHandMeshFB(XrHandTrackerEXT handTracker, XrHandTrackingMeshFB *mesh)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", handTracker, mesh);
-    return ((wine_XrHandTrackerEXT *)handTracker)->wine_session->wine_instance->funcs.p_xrGetHandMeshFB(((wine_XrHandTrackerEXT *)handTracker)->hand_tracker, mesh);
+    ret = (*get_dispatch_table((uint64_t)(handTracker))).p_xrGetHandMeshFB(handTracker, mesh);
+    return ret;
 }
 
 XrResult WINAPI wine_xrGetInputSourceLocalizedName(XrSession session, const XrInputSourceLocalizedNameGetInfo *getInfo, uint32_t bufferCapacityInput, uint32_t *bufferCountOutput, char *buffer)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %u, %p, %p\n", session, getInfo, bufferCapacityInput, bufferCountOutput, buffer);
-    return xrGetInputSourceLocalizedName(((wine_XrSession *)session)->session, getInfo, bufferCapacityInput, bufferCountOutput, buffer);
+    ret = xrGetInputSourceLocalizedName(((wine_XrSession *)session)->session, getInfo, bufferCapacityInput, bufferCountOutput, buffer);
+    return ret;
 }
 
 XrResult WINAPI wine_xrGetInstanceProperties(XrInstance instance, XrInstanceProperties *instanceProperties)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", instance, instanceProperties);
-    return xrGetInstanceProperties(((wine_XrInstance *)instance)->instance, instanceProperties);
+    ret = xrGetInstanceProperties(((wine_XrInstance *)instance)->instance, instanceProperties);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetOpenGLGraphicsRequirementsKHR(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsOpenGLKHR *graphicsRequirements)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %p\n", instance, wine_dbgstr_longlong(systemId), graphicsRequirements);
-    return ((wine_XrInstance *)instance)->funcs.p_xrGetOpenGLGraphicsRequirementsKHR(((wine_XrInstance *)instance)->instance, systemId, graphicsRequirements);
+    ret = ((wine_XrInstance *)instance)->funcs.p_xrGetOpenGLGraphicsRequirementsKHR(((wine_XrInstance *)instance)->instance, systemId, graphicsRequirements);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetPerformanceMetricsStateMETA(XrSession session, XrPerformanceMetricsStateMETA *state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", session, state);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetPerformanceMetricsStateMETA(((wine_XrSession *)session)->session, state);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetPerformanceMetricsStateMETA(((wine_XrSession *)session)->session, state);
+    return ret;
 }
 
 XrResult WINAPI wine_xrGetReferenceSpaceBoundsRect(XrSession session, XrReferenceSpaceType referenceSpaceType, XrExtent2Df *bounds)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %#x, %p\n", session, referenceSpaceType, bounds);
-    return xrGetReferenceSpaceBoundsRect(((wine_XrSession *)session)->session, referenceSpaceType, bounds);
+    ret = xrGetReferenceSpaceBoundsRect(((wine_XrSession *)session)->session, referenceSpaceType, bounds);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetRenderModelPropertiesFB(XrSession session, XrPath path, XrRenderModelPropertiesFB *properties)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %p\n", session, wine_dbgstr_longlong(path), properties);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetRenderModelPropertiesFB(((wine_XrSession *)session)->session, path, properties);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetRenderModelPropertiesFB(((wine_XrSession *)session)->session, path, properties);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetSceneComponentsMSFT(XrSceneMSFT scene, const XrSceneComponentsGetInfoMSFT *getInfo, XrSceneComponentsMSFT *components)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", scene, getInfo, components);
-    return ((wine_XrSceneMSFT *)scene)->wine_scene_observer_msft->wine_session->wine_instance->funcs.p_xrGetSceneComponentsMSFT(((wine_XrSceneMSFT *)scene)->scene_msft, getInfo, components);
+    ret = (*get_dispatch_table((uint64_t)(scene))).p_xrGetSceneComponentsMSFT(scene, getInfo, components);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetSceneComputeStateMSFT(XrSceneObserverMSFT sceneObserver, XrSceneComputeStateMSFT *state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", sceneObserver, state);
-    return ((wine_XrSceneObserverMSFT *)sceneObserver)->wine_session->wine_instance->funcs.p_xrGetSceneComputeStateMSFT(((wine_XrSceneObserverMSFT *)sceneObserver)->scene_observer_msft, state);
+    ret = (*get_dispatch_table((uint64_t)(sceneObserver))).p_xrGetSceneComputeStateMSFT(sceneObserver, state);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetSceneMeshBuffersMSFT(XrSceneMSFT scene, const XrSceneMeshBuffersGetInfoMSFT *getInfo, XrSceneMeshBuffersMSFT *buffers)
@@ -427,361 +812,538 @@ static XrResult WINAPI wine_xrGetSceneMeshBuffersMSFT(XrSceneMSFT scene, const X
     WINE_TRACE("%p, %p, %p\n", scene, getInfo, buffers);
 
     convert_XrSceneMeshBuffersGetInfoMSFT_win_to_host(getInfo, &getInfo_host);
-    result = ((wine_XrSceneMSFT *)scene)->wine_scene_observer_msft->wine_session->wine_instance->funcs.p_xrGetSceneMeshBuffersMSFT(((wine_XrSceneMSFT *)scene)->scene_msft, &getInfo_host, buffers);
+    result = (*get_dispatch_table((uint64_t)(scene))).p_xrGetSceneMeshBuffersMSFT(scene, &getInfo_host, buffers);
 
     return result;
 #else
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", scene, getInfo, buffers);
-    return ((wine_XrSceneMSFT *)scene)->wine_scene_observer_msft->wine_session->wine_instance->funcs.p_xrGetSceneMeshBuffersMSFT(((wine_XrSceneMSFT *)scene)->scene_msft, getInfo, buffers);
+    ret = (*get_dispatch_table((uint64_t)(scene))).p_xrGetSceneMeshBuffersMSFT(scene, getInfo, buffers);
+    return ret;
 #endif
 }
 
 static XrResult WINAPI wine_xrGetSerializedSceneFragmentDataMSFT(XrSceneMSFT scene, const XrSerializedSceneFragmentDataGetInfoMSFT *getInfo, uint32_t countInput, uint32_t *readOutput, uint8_t *buffer)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %u, %p, %p\n", scene, getInfo, countInput, readOutput, buffer);
-    return ((wine_XrSceneMSFT *)scene)->wine_scene_observer_msft->wine_session->wine_instance->funcs.p_xrGetSerializedSceneFragmentDataMSFT(((wine_XrSceneMSFT *)scene)->scene_msft, getInfo, countInput, readOutput, buffer);
+    ret = (*get_dispatch_table((uint64_t)(scene))).p_xrGetSerializedSceneFragmentDataMSFT(scene, getInfo, countInput, readOutput, buffer);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetSwapchainStateFB(XrSwapchain swapchain, XrSwapchainStateBaseHeaderFB *state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", swapchain, state);
-    return ((wine_XrSwapchain *)swapchain)->wine_session->wine_instance->funcs.p_xrGetSwapchainStateFB(((wine_XrSwapchain *)swapchain)->swapchain, state);
+    ret = ((wine_XrSwapchain *)swapchain)->wine_session->wine_instance->funcs.p_xrGetSwapchainStateFB(((wine_XrSwapchain *)swapchain)->swapchain, state);
+    return ret;
 }
 
 XrResult WINAPI wine_xrGetSystemProperties(XrInstance instance, XrSystemId systemId, XrSystemProperties *properties)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %p\n", instance, wine_dbgstr_longlong(systemId), properties);
-    return xrGetSystemProperties(((wine_XrInstance *)instance)->instance, systemId, properties);
+    ret = xrGetSystemProperties(((wine_XrInstance *)instance)->instance, systemId, properties);
+    return ret;
 }
 
 XrResult WINAPI wine_xrGetViewConfigurationProperties(XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, XrViewConfigurationProperties *configurationProperties)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %#x, %p\n", instance, wine_dbgstr_longlong(systemId), viewConfigurationType, configurationProperties);
-    return xrGetViewConfigurationProperties(((wine_XrInstance *)instance)->instance, systemId, viewConfigurationType, configurationProperties);
+    ret = xrGetViewConfigurationProperties(((wine_XrInstance *)instance)->instance, systemId, viewConfigurationType, configurationProperties);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetVisibilityMaskKHR(XrSession session, XrViewConfigurationType viewConfigurationType, uint32_t viewIndex, XrVisibilityMaskTypeKHR visibilityMaskType, XrVisibilityMaskKHR *visibilityMask)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %#x, %u, %#x, %p\n", session, viewConfigurationType, viewIndex, visibilityMaskType, visibilityMask);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetVisibilityMaskKHR(((wine_XrSession *)session)->session, viewConfigurationType, viewIndex, visibilityMaskType, visibilityMask);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrGetVisibilityMaskKHR(((wine_XrSession *)session)->session, viewConfigurationType, viewIndex, visibilityMaskType, visibilityMask);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetVulkanGraphicsRequirements2KHR(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsVulkanKHR *graphicsRequirements)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %p\n", instance, wine_dbgstr_longlong(systemId), graphicsRequirements);
-    return ((wine_XrInstance *)instance)->funcs.p_xrGetVulkanGraphicsRequirements2KHR(((wine_XrInstance *)instance)->instance, systemId, graphicsRequirements);
+    ret = ((wine_XrInstance *)instance)->funcs.p_xrGetVulkanGraphicsRequirements2KHR(((wine_XrInstance *)instance)->instance, systemId, graphicsRequirements);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrGetVulkanGraphicsRequirementsKHR(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsVulkanKHR *graphicsRequirements)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %p\n", instance, wine_dbgstr_longlong(systemId), graphicsRequirements);
-    return ((wine_XrInstance *)instance)->funcs.p_xrGetVulkanGraphicsRequirementsKHR(((wine_XrInstance *)instance)->instance, systemId, graphicsRequirements);
+    ret = ((wine_XrInstance *)instance)->funcs.p_xrGetVulkanGraphicsRequirementsKHR(((wine_XrInstance *)instance)->instance, systemId, graphicsRequirements);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrLoadControllerModelMSFT(XrSession session, XrControllerModelKeyMSFT modelKey, uint32_t bufferCapacityInput, uint32_t *bufferCountOutput, uint8_t *buffer)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %u, %p, %p\n", session, wine_dbgstr_longlong(modelKey), bufferCapacityInput, bufferCountOutput, buffer);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrLoadControllerModelMSFT(((wine_XrSession *)session)->session, modelKey, bufferCapacityInput, bufferCountOutput, buffer);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrLoadControllerModelMSFT(((wine_XrSession *)session)->session, modelKey, bufferCapacityInput, bufferCountOutput, buffer);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrLoadRenderModelFB(XrSession session, const XrRenderModelLoadInfoFB *info, XrRenderModelBufferFB *buffer)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, info, buffer);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrLoadRenderModelFB(((wine_XrSession *)session)->session, info, buffer);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrLoadRenderModelFB(((wine_XrSession *)session)->session, info, buffer);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrLocateHandJointsEXT(XrHandTrackerEXT handTracker, const XrHandJointsLocateInfoEXT *locateInfo, XrHandJointLocationsEXT *locations)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", handTracker, locateInfo, locations);
-    return ((wine_XrHandTrackerEXT *)handTracker)->wine_session->wine_instance->funcs.p_xrLocateHandJointsEXT(((wine_XrHandTrackerEXT *)handTracker)->hand_tracker, locateInfo, locations);
+    ret = (*get_dispatch_table((uint64_t)(handTracker))).p_xrLocateHandJointsEXT(handTracker, locateInfo, locations);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrLocateSceneComponentsMSFT(XrSceneMSFT scene, const XrSceneComponentsLocateInfoMSFT *locateInfo, XrSceneComponentLocationsMSFT *locations)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", scene, locateInfo, locations);
-    return ((wine_XrSceneMSFT *)scene)->wine_scene_observer_msft->wine_session->wine_instance->funcs.p_xrLocateSceneComponentsMSFT(((wine_XrSceneMSFT *)scene)->scene_msft, locateInfo, locations);
+    ret = (*get_dispatch_table((uint64_t)(scene))).p_xrLocateSceneComponentsMSFT(scene, locateInfo, locations);
+    return ret;
 }
 
 XrResult WINAPI wine_xrLocateSpace(XrSpace space, XrSpace baseSpace, XrTime time, XrSpaceLocation *location)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, 0x%s, %p\n", space, baseSpace, wine_dbgstr_longlong(time), location);
-    return xrLocateSpace(space, baseSpace, time, location);
+    ret = xrLocateSpace(space, baseSpace, time, location);
+    return ret;
 }
 
 XrResult WINAPI wine_xrLocateViews(XrSession session, const XrViewLocateInfo *viewLocateInfo, XrViewState *viewState, uint32_t viewCapacityInput, uint32_t *viewCountOutput, XrView *views)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p, %u, %p, %p\n", session, viewLocateInfo, viewState, viewCapacityInput, viewCountOutput, views);
-    return xrLocateViews(((wine_XrSession *)session)->session, viewLocateInfo, viewState, viewCapacityInput, viewCountOutput, views);
+    ret = xrLocateViews(((wine_XrSession *)session)->session, viewLocateInfo, viewState, viewCapacityInput, viewCountOutput, views);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrPassthroughLayerPauseFB(XrPassthroughLayerFB layer)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", layer);
-    return ((wine_XrPassthroughLayerFB *)layer)->wine_session->wine_instance->funcs.p_xrPassthroughLayerPauseFB(((wine_XrPassthroughLayerFB *)layer)->layer);
+    ret = (*get_dispatch_table((uint64_t)(layer))).p_xrPassthroughLayerPauseFB(layer);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrPassthroughLayerResumeFB(XrPassthroughLayerFB layer)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", layer);
-    return ((wine_XrPassthroughLayerFB *)layer)->wine_session->wine_instance->funcs.p_xrPassthroughLayerResumeFB(((wine_XrPassthroughLayerFB *)layer)->layer);
+    ret = (*get_dispatch_table((uint64_t)(layer))).p_xrPassthroughLayerResumeFB(layer);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrPassthroughLayerSetKeyboardHandsIntensityFB(XrPassthroughLayerFB layer, const XrPassthroughKeyboardHandsIntensityFB *intensity)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", layer, intensity);
-    return ((wine_XrPassthroughLayerFB *)layer)->wine_session->wine_instance->funcs.p_xrPassthroughLayerSetKeyboardHandsIntensityFB(((wine_XrPassthroughLayerFB *)layer)->layer, intensity);
+    ret = (*get_dispatch_table((uint64_t)(layer))).p_xrPassthroughLayerSetKeyboardHandsIntensityFB(layer, intensity);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrPassthroughLayerSetStyleFB(XrPassthroughLayerFB layer, const XrPassthroughStyleFB *style)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", layer, style);
-    return ((wine_XrPassthroughLayerFB *)layer)->wine_session->wine_instance->funcs.p_xrPassthroughLayerSetStyleFB(((wine_XrPassthroughLayerFB *)layer)->layer, style);
+    ret = (*get_dispatch_table((uint64_t)(layer))).p_xrPassthroughLayerSetStyleFB(layer, style);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrPassthroughPauseFB(XrPassthroughFB passthrough)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", passthrough);
-    return ((wine_XrPassthroughFB *)passthrough)->wine_session->wine_instance->funcs.p_xrPassthroughPauseFB(((wine_XrPassthroughFB *)passthrough)->passthrough);
+    ret = (*get_dispatch_table((uint64_t)(passthrough))).p_xrPassthroughPauseFB(passthrough);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrPassthroughStartFB(XrPassthroughFB passthrough)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", passthrough);
-    return ((wine_XrPassthroughFB *)passthrough)->wine_session->wine_instance->funcs.p_xrPassthroughStartFB(((wine_XrPassthroughFB *)passthrough)->passthrough);
+    ret = (*get_dispatch_table((uint64_t)(passthrough))).p_xrPassthroughStartFB(passthrough);
+    return ret;
 }
 
 XrResult WINAPI wine_xrPathToString(XrInstance instance, XrPath path, uint32_t bufferCapacityInput, uint32_t *bufferCountOutput, char *buffer)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %u, %p, %p\n", instance, wine_dbgstr_longlong(path), bufferCapacityInput, bufferCountOutput, buffer);
-    return xrPathToString(((wine_XrInstance *)instance)->instance, path, bufferCapacityInput, bufferCountOutput, buffer);
+    ret = xrPathToString(((wine_XrInstance *)instance)->instance, path, bufferCapacityInput, bufferCountOutput, buffer);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrPerfSettingsSetPerformanceLevelEXT(XrSession session, XrPerfSettingsDomainEXT domain, XrPerfSettingsLevelEXT level)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %#x, %#x\n", session, domain, level);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrPerfSettingsSetPerformanceLevelEXT(((wine_XrSession *)session)->session, domain, level);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrPerfSettingsSetPerformanceLevelEXT(((wine_XrSession *)session)->session, domain, level);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrPersistSpatialAnchorMSFT(XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore, const XrSpatialAnchorPersistenceInfoMSFT *spatialAnchorPersistenceInfo)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", spatialAnchorStore, spatialAnchorPersistenceInfo);
-    return ((wine_XrSpatialAnchorStoreConnectionMSFT *)spatialAnchorStore)->wine_session->wine_instance->funcs.p_xrPersistSpatialAnchorMSFT(((wine_XrSpatialAnchorStoreConnectionMSFT *)spatialAnchorStore)->spatial_anchor_store_connection, spatialAnchorPersistenceInfo);
+    ret = (*get_dispatch_table((uint64_t)(spatialAnchorStore))).p_xrPersistSpatialAnchorMSFT(spatialAnchorStore, spatialAnchorPersistenceInfo);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrQueryPerformanceMetricsCounterMETA(XrSession session, XrPath counterPath, XrPerformanceMetricsCounterMETA *counter)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %p\n", session, wine_dbgstr_longlong(counterPath), counter);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrQueryPerformanceMetricsCounterMETA(((wine_XrSession *)session)->session, counterPath, counter);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrQueryPerformanceMetricsCounterMETA(((wine_XrSession *)session)->session, counterPath, counter);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrQuerySpacesFB(XrSession session, const XrSpaceQueryInfoBaseHeaderFB *info, XrAsyncRequestIdFB *requestId)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, info, requestId);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrQuerySpacesFB(((wine_XrSession *)session)->session, info, requestId);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrQuerySpacesFB(((wine_XrSession *)session)->session, info, requestId);
+    return ret;
 }
 
 XrResult WINAPI wine_xrReleaseSwapchainImage(XrSwapchain swapchain, const XrSwapchainImageReleaseInfo *releaseInfo)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", swapchain, releaseInfo);
-    return xrReleaseSwapchainImage(((wine_XrSwapchain *)swapchain)->swapchain, releaseInfo);
+    ret = xrReleaseSwapchainImage(((wine_XrSwapchain *)swapchain)->swapchain, releaseInfo);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrRequestDisplayRefreshRateFB(XrSession session, float displayRefreshRate)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %f\n", session, displayRefreshRate);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrRequestDisplayRefreshRateFB(((wine_XrSession *)session)->session, displayRefreshRate);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrRequestDisplayRefreshRateFB(((wine_XrSession *)session)->session, displayRefreshRate);
+    return ret;
 }
 
 XrResult WINAPI wine_xrRequestExitSession(XrSession session)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", session);
-    return xrRequestExitSession(((wine_XrSession *)session)->session);
+    ret = xrRequestExitSession(((wine_XrSession *)session)->session);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrRequestSceneCaptureFB(XrSession session, const XrSceneCaptureRequestInfoFB *info, XrAsyncRequestIdFB *requestId)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, info, requestId);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrRequestSceneCaptureFB(((wine_XrSession *)session)->session, info, requestId);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrRequestSceneCaptureFB(((wine_XrSession *)session)->session, info, requestId);
+    return ret;
 }
 
 XrResult WINAPI wine_xrResultToString(XrInstance instance, XrResult value, char buffer[])
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %#x, %p\n", instance, value, buffer);
-    return xrResultToString(((wine_XrInstance *)instance)->instance, value, buffer);
+    ret = xrResultToString(((wine_XrInstance *)instance)->instance, value, buffer);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrRetrieveSpaceQueryResultsFB(XrSession session, XrAsyncRequestIdFB requestId, XrSpaceQueryResultsFB *results)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, %p\n", session, wine_dbgstr_longlong(requestId), results);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrRetrieveSpaceQueryResultsFB(((wine_XrSession *)session)->session, requestId, results);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrRetrieveSpaceQueryResultsFB(((wine_XrSession *)session)->session, requestId, results);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSaveSpaceListFB(XrSession session, const XrSpaceListSaveInfoFB *info, XrAsyncRequestIdFB *requestId)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, info, requestId);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSaveSpaceListFB(((wine_XrSession *)session)->session, info, requestId);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSaveSpaceListFB(((wine_XrSession *)session)->session, info, requestId);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSetColorSpaceFB(XrSession session, const XrColorSpaceFB colorspace)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %#x\n", session, colorspace);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetColorSpaceFB(((wine_XrSession *)session)->session, colorspace);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetColorSpaceFB(((wine_XrSession *)session)->session, colorspace);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSetDigitalLensControlALMALENCE(XrSession session, const XrDigitalLensControlALMALENCE *digitalLensControl)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", session, digitalLensControl);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetDigitalLensControlALMALENCE(((wine_XrSession *)session)->session, digitalLensControl);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetDigitalLensControlALMALENCE(((wine_XrSession *)session)->session, digitalLensControl);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSetEnvironmentDepthEstimationVARJO(XrSession session, XrBool32 enabled)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %u\n", session, enabled);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetEnvironmentDepthEstimationVARJO(((wine_XrSession *)session)->session, enabled);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetEnvironmentDepthEstimationVARJO(((wine_XrSession *)session)->session, enabled);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSetInputDeviceActiveEXT(XrSession session, XrPath interactionProfile, XrPath topLevelPath, XrBool32 isActive)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, 0x%s, %u\n", session, wine_dbgstr_longlong(interactionProfile), wine_dbgstr_longlong(topLevelPath), isActive);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetInputDeviceActiveEXT(((wine_XrSession *)session)->session, interactionProfile, topLevelPath, isActive);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetInputDeviceActiveEXT(((wine_XrSession *)session)->session, interactionProfile, topLevelPath, isActive);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSetInputDeviceLocationEXT(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, XrSpace space, XrPosef pose)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, 0x%s, %p, {{%f, %f, %f, %f}, {%f %f %f}}\n", session, wine_dbgstr_longlong(topLevelPath), wine_dbgstr_longlong(inputSourcePath), space, pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w, pose.position.x, pose.position.y, pose.position.z);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetInputDeviceLocationEXT(((wine_XrSession *)session)->session, topLevelPath, inputSourcePath, space, pose);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetInputDeviceLocationEXT(((wine_XrSession *)session)->session, topLevelPath, inputSourcePath, space, pose);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSetInputDeviceStateBoolEXT(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, XrBool32 state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, 0x%s, %u\n", session, wine_dbgstr_longlong(topLevelPath), wine_dbgstr_longlong(inputSourcePath), state);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetInputDeviceStateBoolEXT(((wine_XrSession *)session)->session, topLevelPath, inputSourcePath, state);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetInputDeviceStateBoolEXT(((wine_XrSession *)session)->session, topLevelPath, inputSourcePath, state);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSetInputDeviceStateFloatEXT(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, float state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, 0x%s, %f\n", session, wine_dbgstr_longlong(topLevelPath), wine_dbgstr_longlong(inputSourcePath), state);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetInputDeviceStateFloatEXT(((wine_XrSession *)session)->session, topLevelPath, inputSourcePath, state);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetInputDeviceStateFloatEXT(((wine_XrSession *)session)->session, topLevelPath, inputSourcePath, state);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSetInputDeviceStateVector2fEXT(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, XrVector2f state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, 0x%s, 0x%s, %f, %f\n", session, wine_dbgstr_longlong(topLevelPath), wine_dbgstr_longlong(inputSourcePath), state.x, state.y);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetInputDeviceStateVector2fEXT(((wine_XrSession *)session)->session, topLevelPath, inputSourcePath, state);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetInputDeviceStateVector2fEXT(((wine_XrSession *)session)->session, topLevelPath, inputSourcePath, state);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSetPerformanceMetricsStateMETA(XrSession session, const XrPerformanceMetricsStateMETA *state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", session, state);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetPerformanceMetricsStateMETA(((wine_XrSession *)session)->session, state);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetPerformanceMetricsStateMETA(((wine_XrSession *)session)->session, state);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSetTrackingOptimizationSettingsHintQCOM(XrSession session, XrTrackingOptimizationSettingsDomainQCOM domain, XrTrackingOptimizationSettingsHintQCOM hint)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %#x, %#x\n", session, domain, hint);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetTrackingOptimizationSettingsHintQCOM(((wine_XrSession *)session)->session, domain, hint);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetTrackingOptimizationSettingsHintQCOM(((wine_XrSession *)session)->session, domain, hint);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrSetViewOffsetVARJO(XrSession session, float offset)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %f\n", session, offset);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetViewOffsetVARJO(((wine_XrSession *)session)->session, offset);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrSetViewOffsetVARJO(((wine_XrSession *)session)->session, offset);
+    return ret;
 }
 
 XrResult WINAPI wine_xrStopHapticFeedback(XrSession session, const XrHapticActionInfo *hapticActionInfo)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", session, hapticActionInfo);
-    return xrStopHapticFeedback(((wine_XrSession *)session)->session, hapticActionInfo);
+    ret = xrStopHapticFeedback(((wine_XrSession *)session)->session, hapticActionInfo);
+    return ret;
 }
 
 XrResult WINAPI wine_xrStringToPath(XrInstance instance, const char *pathString, XrPath *path)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", instance, pathString, path);
-    return xrStringToPath(((wine_XrInstance *)instance)->instance, pathString, path);
+    ret = xrStringToPath(((wine_XrInstance *)instance)->instance, pathString, path);
+    return ret;
 }
 
 XrResult WINAPI wine_xrStructureTypeToString(XrInstance instance, XrStructureType value, char buffer[])
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %#x, %p\n", instance, value, buffer);
-    return xrStructureTypeToString(((wine_XrInstance *)instance)->instance, value, buffer);
+    ret = xrStructureTypeToString(((wine_XrInstance *)instance)->instance, value, buffer);
+    return ret;
 }
 
 XrResult WINAPI wine_xrSuggestInteractionProfileBindings(XrInstance instance, const XrInteractionProfileSuggestedBinding *suggestedBindings)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", instance, suggestedBindings);
-    return xrSuggestInteractionProfileBindings(((wine_XrInstance *)instance)->instance, suggestedBindings);
+    ret = xrSuggestInteractionProfileBindings(((wine_XrInstance *)instance)->instance, suggestedBindings);
+    return ret;
 }
 
 XrResult WINAPI wine_xrSyncActions(XrSession session, const XrActionsSyncInfo *syncInfo)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", session, syncInfo);
-    return xrSyncActions(((wine_XrSession *)session)->session, syncInfo);
+    ret = xrSyncActions(((wine_XrSession *)session)->session, syncInfo);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrThermalGetTemperatureTrendEXT(XrSession session, XrPerfSettingsDomainEXT domain, XrPerfSettingsNotificationLevelEXT *notificationLevel, float *tempHeadroom, float *tempSlope)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %#x, %p, %p, %p\n", session, domain, notificationLevel, tempHeadroom, tempSlope);
-    return ((wine_XrSession *)session)->wine_instance->funcs.p_xrThermalGetTemperatureTrendEXT(((wine_XrSession *)session)->session, domain, notificationLevel, tempHeadroom, tempSlope);
+    ret = ((wine_XrSession *)session)->wine_instance->funcs.p_xrThermalGetTemperatureTrendEXT(((wine_XrSession *)session)->session, domain, notificationLevel, tempHeadroom, tempSlope);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrTriangleMeshBeginUpdateFB(XrTriangleMeshFB mesh)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", mesh);
-    return ((wine_XrTriangleMeshFB *)mesh)->wine_session->wine_instance->funcs.p_xrTriangleMeshBeginUpdateFB(((wine_XrTriangleMeshFB *)mesh)->mesh);
+    ret = (*get_dispatch_table((uint64_t)(mesh))).p_xrTriangleMeshBeginUpdateFB(mesh);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrTriangleMeshBeginVertexBufferUpdateFB(XrTriangleMeshFB mesh, uint32_t *outVertexCount)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", mesh, outVertexCount);
-    return ((wine_XrTriangleMeshFB *)mesh)->wine_session->wine_instance->funcs.p_xrTriangleMeshBeginVertexBufferUpdateFB(((wine_XrTriangleMeshFB *)mesh)->mesh, outVertexCount);
+    ret = (*get_dispatch_table((uint64_t)(mesh))).p_xrTriangleMeshBeginVertexBufferUpdateFB(mesh, outVertexCount);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrTriangleMeshEndUpdateFB(XrTriangleMeshFB mesh, uint32_t vertexCount, uint32_t triangleCount)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %u, %u\n", mesh, vertexCount, triangleCount);
-    return ((wine_XrTriangleMeshFB *)mesh)->wine_session->wine_instance->funcs.p_xrTriangleMeshEndUpdateFB(((wine_XrTriangleMeshFB *)mesh)->mesh, vertexCount, triangleCount);
+    ret = (*get_dispatch_table((uint64_t)(mesh))).p_xrTriangleMeshEndUpdateFB(mesh, vertexCount, triangleCount);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrTriangleMeshEndVertexBufferUpdateFB(XrTriangleMeshFB mesh)
 {
+    XrResult ret;
+
     WINE_TRACE("%p\n", mesh);
-    return ((wine_XrTriangleMeshFB *)mesh)->wine_session->wine_instance->funcs.p_xrTriangleMeshEndVertexBufferUpdateFB(((wine_XrTriangleMeshFB *)mesh)->mesh);
+    ret = (*get_dispatch_table((uint64_t)(mesh))).p_xrTriangleMeshEndVertexBufferUpdateFB(mesh);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrTriangleMeshGetIndexBufferFB(XrTriangleMeshFB mesh, uint32_t **outIndexBuffer)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", mesh, outIndexBuffer);
-    return ((wine_XrTriangleMeshFB *)mesh)->wine_session->wine_instance->funcs.p_xrTriangleMeshGetIndexBufferFB(((wine_XrTriangleMeshFB *)mesh)->mesh, outIndexBuffer);
+    ret = (*get_dispatch_table((uint64_t)(mesh))).p_xrTriangleMeshGetIndexBufferFB(mesh, outIndexBuffer);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrTriangleMeshGetVertexBufferFB(XrTriangleMeshFB mesh, XrVector3f **outVertexBuffer)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", mesh, outVertexBuffer);
-    return ((wine_XrTriangleMeshFB *)mesh)->wine_session->wine_instance->funcs.p_xrTriangleMeshGetVertexBufferFB(((wine_XrTriangleMeshFB *)mesh)->mesh, outVertexBuffer);
+    ret = (*get_dispatch_table((uint64_t)(mesh))).p_xrTriangleMeshGetVertexBufferFB(mesh, outVertexBuffer);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrUnpersistSpatialAnchorMSFT(XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore, const XrSpatialAnchorPersistenceNameMSFT *spatialAnchorPersistenceName)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", spatialAnchorStore, spatialAnchorPersistenceName);
-    return ((wine_XrSpatialAnchorStoreConnectionMSFT *)spatialAnchorStore)->wine_session->wine_instance->funcs.p_xrUnpersistSpatialAnchorMSFT(((wine_XrSpatialAnchorStoreConnectionMSFT *)spatialAnchorStore)->spatial_anchor_store_connection, spatialAnchorPersistenceName);
+    ret = (*get_dispatch_table((uint64_t)(spatialAnchorStore))).p_xrUnpersistSpatialAnchorMSFT(spatialAnchorStore, spatialAnchorPersistenceName);
+    return ret;
 }
 
 static XrResult WINAPI wine_xrUpdateSwapchainFB(XrSwapchain swapchain, const XrSwapchainStateBaseHeaderFB *state)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", swapchain, state);
-    return ((wine_XrSwapchain *)swapchain)->wine_session->wine_instance->funcs.p_xrUpdateSwapchainFB(((wine_XrSwapchain *)swapchain)->swapchain, state);
+    ret = ((wine_XrSwapchain *)swapchain)->wine_session->wine_instance->funcs.p_xrUpdateSwapchainFB(((wine_XrSwapchain *)swapchain)->swapchain, state);
+    return ret;
 }
 
 XrResult WINAPI wine_xrWaitFrame(XrSession session, const XrFrameWaitInfo *frameWaitInfo, XrFrameState *frameState)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p, %p\n", session, frameWaitInfo, frameState);
-    return xrWaitFrame(((wine_XrSession *)session)->session, frameWaitInfo, frameState);
+    ret = xrWaitFrame(((wine_XrSession *)session)->session, frameWaitInfo, frameState);
+    return ret;
 }
 
 XrResult WINAPI wine_xrWaitSwapchainImage(XrSwapchain swapchain, const XrSwapchainImageWaitInfo *waitInfo)
 {
+    XrResult ret;
+
     WINE_TRACE("%p, %p\n", swapchain, waitInfo);
-    return xrWaitSwapchainImage(((wine_XrSwapchain *)swapchain)->swapchain, waitInfo);
+    ret = xrWaitSwapchainImage(((wine_XrSwapchain *)swapchain)->swapchain, waitInfo);
+    return ret;
 }
 
 static const struct openxr_func xr_dispatch_table[] =
diff --git a/wineopenxr/openxr_thunks.h b/wineopenxr/openxr_thunks.h
index 34416ff6..176d2ef7 100644
--- a/wineopenxr/openxr_thunks.h
+++ b/wineopenxr/openxr_thunks.h
@@ -27,35 +27,14 @@
 /* Functions for which we have custom implementations outside of the thunks. */
 XrResult WINAPI wine_xrConvertTimeToWin32PerformanceCounterKHR(XrInstance instance, XrTime time, LARGE_INTEGER *performanceCounter);
 XrResult WINAPI wine_xrConvertWin32PerformanceCounterToTimeKHR(XrInstance instance, const LARGE_INTEGER *performanceCounter, XrTime *time);
-XrResult WINAPI wine_xrCreateFoveationProfileFB(XrSession session, const XrFoveationProfileCreateInfoFB *createInfo, XrFoveationProfileFB *profile);
-XrResult WINAPI wine_xrCreateGeometryInstanceFB(XrSession session, const XrGeometryInstanceCreateInfoFB *createInfo, XrGeometryInstanceFB *outGeometryInstance);
-XrResult WINAPI wine_xrCreateHandTrackerEXT(XrSession session, const XrHandTrackerCreateInfoEXT *createInfo, XrHandTrackerEXT *handTracker);
 XrResult WINAPI wine_xrCreateInstance(const XrInstanceCreateInfo *createInfo, XrInstance *instance);
-XrResult WINAPI wine_xrCreatePassthroughFB(XrSession session, const XrPassthroughCreateInfoFB *createInfo, XrPassthroughFB *outPassthrough);
-XrResult WINAPI wine_xrCreatePassthroughLayerFB(XrSession session, const XrPassthroughLayerCreateInfoFB *createInfo, XrPassthroughLayerFB *outLayer);
-XrResult WINAPI wine_xrCreateSceneMSFT(XrSceneObserverMSFT sceneObserver, const XrSceneCreateInfoMSFT *createInfo, XrSceneMSFT *scene);
-XrResult WINAPI wine_xrCreateSceneObserverMSFT(XrSession session, const XrSceneObserverCreateInfoMSFT *createInfo, XrSceneObserverMSFT *sceneObserver);
 XrResult WINAPI wine_xrCreateSession(XrInstance instance, const XrSessionCreateInfo *createInfo, XrSession *session);
-XrResult WINAPI wine_xrCreateSpatialAnchorFromPersistedNameMSFT(XrSession session, const XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT *spatialAnchorCreateInfo, XrSpatialAnchorMSFT *spatialAnchor);
-XrResult WINAPI wine_xrCreateSpatialAnchorMSFT(XrSession session, const XrSpatialAnchorCreateInfoMSFT *createInfo, XrSpatialAnchorMSFT *anchor);
-XrResult WINAPI wine_xrCreateSpatialAnchorStoreConnectionMSFT(XrSession session, XrSpatialAnchorStoreConnectionMSFT *spatialAnchorStore);
 XrResult WINAPI wine_xrCreateSwapchain(XrSession session, const XrSwapchainCreateInfo *createInfo, XrSwapchain *swapchain);
-XrResult WINAPI wine_xrCreateTriangleMeshFB(XrSession session, const XrTriangleMeshCreateInfoFB *createInfo, XrTriangleMeshFB *outTriangleMesh);
 XrResult WINAPI wine_xrCreateVulkanDeviceKHR(XrInstance instance, const XrVulkanDeviceCreateInfoKHR *createInfo, VkDevice *vulkanDevice, VkResult *vulkanResult);
 XrResult WINAPI wine_xrCreateVulkanInstanceKHR(XrInstance instance, const XrVulkanInstanceCreateInfoKHR *createInfo, VkInstance *vulkanInstance, VkResult *vulkanResult);
-XrResult WINAPI wine_xrDestroyFoveationProfileFB(XrFoveationProfileFB profile);
-XrResult WINAPI wine_xrDestroyGeometryInstanceFB(XrGeometryInstanceFB instance);
-XrResult WINAPI wine_xrDestroyHandTrackerEXT(XrHandTrackerEXT handTracker);
 XrResult WINAPI wine_xrDestroyInstance(XrInstance instance);
-XrResult WINAPI wine_xrDestroyPassthroughFB(XrPassthroughFB passthrough);
-XrResult WINAPI wine_xrDestroyPassthroughLayerFB(XrPassthroughLayerFB layer);
-XrResult WINAPI wine_xrDestroySceneMSFT(XrSceneMSFT scene);
-XrResult WINAPI wine_xrDestroySceneObserverMSFT(XrSceneObserverMSFT sceneObserver);
 XrResult WINAPI wine_xrDestroySession(XrSession session);
-XrResult WINAPI wine_xrDestroySpatialAnchorMSFT(XrSpatialAnchorMSFT anchor);
-XrResult WINAPI wine_xrDestroySpatialAnchorStoreConnectionMSFT(XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore);
 XrResult WINAPI wine_xrDestroySwapchain(XrSwapchain swapchain);
-XrResult WINAPI wine_xrDestroyTriangleMeshFB(XrTriangleMeshFB mesh);
 XrResult WINAPI wine_xrEndFrame(XrSession session, const XrFrameEndInfo *frameEndInfo);
 XrResult WINAPI wine_xrEnumerateInstanceExtensionProperties(const char *layerName, uint32_t propertyCapacityInput, uint32_t *propertyCountOutput, XrExtensionProperties *properties);
 XrResult WINAPI wine_xrEnumerateSwapchainFormats(XrSession session, uint32_t formatCapacityInput, uint32_t *formatCountOutput, int64_t *formats);