Skip to content

Commit

Permalink
RHICmdList hook: Fix case where wrong execute index is used
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Feb 27, 2024
1 parent 754aa99 commit bf6e57c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/mods/VR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1993,6 +1993,8 @@ void VR::on_frame() {
void VR::on_present() {
ZoneScopedN(__FUNCTION__);

m_present_thread_id = GetCurrentThreadId();

utility::ScopeGuard _guard {[&]() {
if (!is_using_afr() || (m_render_frame_count + 1) % 2 == m_left_eye_interval) {
SetEvent(m_present_finished_event);
Expand Down
6 changes: 6 additions & 0 deletions src/mods/VR.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,10 @@ class VR : public Mod {
return m_d3d12;
}

uint32_t get_present_thread_id() const {
return m_present_thread_id;
}

private:
Vector4f get_position_unsafe(uint32_t index) const;
Vector4f get_velocity_unsafe(uint32_t index) const;
Expand Down Expand Up @@ -1016,6 +1020,8 @@ class VR : public Mod {
bool m_disable_view_matrix_override{false};
bool m_disable_backbuffer_size_override{false};

uint32_t m_present_thread_id{};

struct XInputContext {
struct PadContext {
using Func = std::function<void(const XINPUT_STATE&, bool is_vr_controller)>;
Expand Down
32 changes: 27 additions & 5 deletions src/mods/vr/FFakeStereoRenderingHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2387,6 +2387,10 @@ struct SceneViewExtensionAnalyzer {
SPDLOG_INFO("Done setting up BeginRenderViewFamily hook!");
}

static inline std::unordered_set<int> tested_execute_indices{};
static inline int correct_execute_index{0};
static inline bool found_correct_execute{false};

template<int N>
static void* hooked_command_fn(sdk::FRHICommandBase_New* cmd, sdk::FRHICommandListBase* cmd_list, void* debug_context, void* r9, void* stack_1, void* stack_2, void* stack_3, void* stack_4, void* stack_5, void* stack_6, void* stack_7, void* stack_8) {
std::scoped_lock _{vtable_mutex};
Expand All @@ -2396,7 +2400,6 @@ struct SceneViewExtensionAnalyzer {

if (once) {
SPDLOG_INFO("[ISceneViewExtension] Successfully hijacked command list! {}", N);
once = false;
}

const auto original_vtable = original_vtables[cmd];
Expand All @@ -2405,20 +2408,41 @@ struct SceneViewExtensionAnalyzer {
const auto func = (decltype(hooked_command_fn<N>)*)original_func;
const auto frame_count = cmd_frame_counts[cmd];

static bool once2 = true;

if (once) {
SPDLOG_INFO("[ISceneViewExtension] Command list frame count: {}", frame_count);
SPDLOG_INFO("[ISceneViewExtension] Original vtable: {:x}", (uintptr_t)original_vtable);
once = false;
}

if (!found_correct_execute && !tested_execute_indices.contains(N) && VR::get()->get_present_thread_id() != 0) {
tested_execute_indices.insert(N);

// N == 0 is a pretty safe heuristic
// Otherwise if >= 1 gets called first, we can assume if the thread is the same
// as the DXGI present thread, then it's the correct execute function
if (N == 0 || GetCurrentThreadId() == VR::get()->get_present_thread_id()) {
correct_execute_index = N;
found_correct_execute = true;
SPDLOG_INFO("[ISceneViewExtension] Found correct execute index: {}", N);
}
}

auto& vr = VR::get();
auto runtime = vr->get_runtime();

auto call_orig = [=]() {
const auto result = func(cmd, cmd_list, debug_context, r9, stack_1, stack_2, stack_3, stack_4, stack_5, stack_6, stack_7, stack_8);

if (N == 0) {
if (N == correct_execute_index) {
runtime->enqueue_render_poses(frame_count);
}

return result;
};

if (N != 0) {
if (N != correct_execute_index) {
return call_orig();
}

Expand Down Expand Up @@ -4448,8 +4472,6 @@ __forceinline Matrix4x4f* FFakeStereoRenderingHook::calculate_stereo_projection_
return out;
}

template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>;

__forceinline void FFakeStereoRenderingHook::render_texture_render_thread(FFakeStereoRendering* stereo, FRHICommandListImmediate* rhi_command_list,
FRHITexture2D* backbuffer, FRHITexture2D* src_texture, double window_size)
{
Expand Down

0 comments on commit bf6e57c

Please sign in to comment.