From f83a2f393cba9b7533aa34b8740bc3a8d0de9f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Wed, 4 Apr 2018 17:20:44 +0200 Subject: [PATCH] vrclient: Call IVRCompositor::SubmitExplicitTimingData() for wined3d D3D11 --- vrclient_x64/gen_wrapper.py | 16 ++++++-- vrclient_x64/vrclient_main.c | 66 +++++++++++++++++++++++++++++++++ vrclient_x64/vrclient_private.h | 6 +++ vrclient_x64/winIVRCompositor.c | 4 +- 4 files changed, 86 insertions(+), 6 deletions(-) diff --git a/vrclient_x64/gen_wrapper.py b/vrclient_x64/gen_wrapper.py index 551a0da7..585a6b52 100755 --- a/vrclient_x64/gen_wrapper.py +++ b/vrclient_x64/gen_wrapper.py @@ -141,10 +141,17 @@ def ivrcompositor_submit(cppname, method): def ivrcompositor_post_present_handoff(cppname, method): return "ivrcompositor_post_present_handoff" +def ivrcompositor_wait_get_poses(cppname, method): + for version in ["021", "022"]: + if version in cppname: + return "ivrcompositor_wait_get_poses" + return None + method_overrides = [ ("IVRSystem", "GetDXGIOutputInfo", ivrsystem_get_dxgi_output_info), ("IVRCompositor", "Submit", ivrcompositor_submit), ("IVRCompositor", "PostPresentHandoff", ivrcompositor_post_present_handoff), + ("IVRCompositor", "WaitGetPoses", ivrcompositor_wait_get_poses), ] method_overrides_data = [ @@ -273,10 +280,11 @@ def handle_method(cfile, classname, winclassname, cppname, method, cpp, cpp_h, e is_method_overridden = False for classname_pattern, methodname, override_generator in method_overrides: if used_name == methodname and classname_pattern in classname: - cfile.write(override_generator(cppname, method)) - cfile.write("(%s_%s, _this->linux_side" % (cppname, used_name)) - is_method_overridden = True - break + fn_name = override_generator(cppname, method) + if fn_name: + cfile.write("%s(%s_%s, _this->linux_side" % (fn_name, cppname, used_name)) + is_method_overridden = True + break else: cfile.write("%s_%s(_this->linux_side" % (cppname, used_name)) diff --git a/vrclient_x64/vrclient_main.c b/vrclient_x64/vrclient_main.c index 1d383c9c..7be601a3 100644 --- a/vrclient_x64/vrclient_main.c +++ b/vrclient_x64/vrclient_main.c @@ -366,3 +366,69 @@ void ivrcompositor_post_present_handoff(void (*cpp_func)(void *), cpp_func(linux_side); } + +struct explicit_timing_data +{ + void *linux_side; + unsigned int version; +}; + +#include "cppIVRCompositor_IVRCompositor_021.h" +#include "cppIVRCompositor_IVRCompositor_022.h" + +static CDECL void d3d11_explicit_timing_callback(const void *data, unsigned int data_size) +{ + const struct explicit_timing_data *callback_data = data; + EVRCompositorError error; + + TRACE("data {%p, %u}\n", data, data_size); + + switch (callback_data->version) + { + case 21: + error = cppIVRCompositor_IVRCompositor_021_SubmitExplicitTimingData(callback_data->linux_side); + break; + case 22: + error = cppIVRCompositor_IVRCompositor_022_SubmitExplicitTimingData(callback_data->linux_side); + break; + default: + ERR("Unexpected version %#x\n", callback_data->version); + } + + if (error) + ERR("error %#x\n", error); +} + +EVRCompositorError ivrcompositor_wait_get_poses( + EVRCompositorError (cpp_func)(void *, TrackedDevicePose_t *, uint32_t, TrackedDevicePose_t *, uint32_t), + void *linux_side, TrackedDevicePose_t *render_poses, uint32_t render_pose_count, + TrackedDevicePose_t *game_poses, uint32_t game_pose_count, + unsigned int version, struct compositor_data *user_data) +{ + struct explicit_timing_data data; + IWineD3D11Device *wined3d_device; + EVRCompositorError r; + + TRACE("%p, %p, %u, %p, %u\n", linux_side, render_poses, render_pose_count, game_poses, game_pose_count); + + r = cpp_func(linux_side, render_poses, render_pose_count, game_poses, game_pose_count); + + if ((wined3d_device = user_data->wined3d_device)) + { + TRACE("wined3d device %p\n", wined3d_device); + + /* We need to call IVRCompositor::SubmitExplicitTimingData() before the + * first flush of the frame. + * + * Sending IVRCompositor::SubmitExplicitTimingData() to the command + * stream immediately after IVRCompositor::WaitGetPoses() seems + * reasonable. + */ + data.linux_side = linux_side; + data.version = version; + wined3d_device->lpVtbl->run_on_command_stream(wined3d_device, + d3d11_explicit_timing_callback, &data, sizeof(data)); + } + + return r; +} diff --git a/vrclient_x64/vrclient_private.h b/vrclient_x64/vrclient_private.h index 08747c5c..20cf19e4 100644 --- a/vrclient_x64/vrclient_private.h +++ b/vrclient_x64/vrclient_private.h @@ -74,6 +74,12 @@ EVRCompositorError ivrcompositor_submit( void ivrcompositor_post_present_handoff(void (*cpp_func)(void *), void *linux_side, unsigned int version, struct compositor_data *user_data); + +EVRCompositorError ivrcompositor_wait_get_poses( + EVRCompositorError (cpp_func)(void *, TrackedDevicePose_t *, uint32_t, TrackedDevicePose_t *, uint32_t), + void *linux_side, TrackedDevicePose_t *render_poses, uint32_t render_pose_count, + TrackedDevicePose_t *game_poses, uint32_t game_pose_count, + unsigned int version, struct compositor_data *user_data); #endif /* __cplusplus */ #define TRACE WINE_TRACE diff --git a/vrclient_x64/winIVRCompositor.c b/vrclient_x64/winIVRCompositor.c index 7b062912..b1f0669d 100644 --- a/vrclient_x64/winIVRCompositor.c +++ b/vrclient_x64/winIVRCompositor.c @@ -42,7 +42,7 @@ DEFINE_THISCALL_WRAPPER(winIVRCompositor_IVRCompositor_022_WaitGetPoses, 28) EVRCompositorError __thiscall winIVRCompositor_IVRCompositor_022_WaitGetPoses(winIVRCompositor_IVRCompositor_022 *_this, TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount) { TRACE("%p\n", _this); - return cppIVRCompositor_IVRCompositor_022_WaitGetPoses(_this->linux_side, pRenderPoseArray, unRenderPoseArrayCount, pGamePoseArray, unGamePoseArrayCount); + return ivrcompositor_wait_get_poses(cppIVRCompositor_IVRCompositor_022_WaitGetPoses, _this->linux_side, pRenderPoseArray, unRenderPoseArrayCount, pGamePoseArray, unGamePoseArrayCount, 22, &_this->user_data); } DEFINE_THISCALL_WRAPPER(winIVRCompositor_IVRCompositor_022_GetLastPoses, 28) @@ -415,7 +415,7 @@ DEFINE_THISCALL_WRAPPER(winIVRCompositor_IVRCompositor_021_WaitGetPoses, 28) EVRCompositorError __thiscall winIVRCompositor_IVRCompositor_021_WaitGetPoses(winIVRCompositor_IVRCompositor_021 *_this, TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount) { TRACE("%p\n", _this); - return cppIVRCompositor_IVRCompositor_021_WaitGetPoses(_this->linux_side, pRenderPoseArray, unRenderPoseArrayCount, pGamePoseArray, unGamePoseArrayCount); + return ivrcompositor_wait_get_poses(cppIVRCompositor_IVRCompositor_021_WaitGetPoses, _this->linux_side, pRenderPoseArray, unRenderPoseArrayCount, pGamePoseArray, unGamePoseArrayCount, 21, &_this->user_data); } DEFINE_THISCALL_WRAPPER(winIVRCompositor_IVRCompositor_021_GetLastPoses, 28)