Skip to content

Commit

Permalink
Merge branch 'master' into pd-upscaler
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Mar 22, 2024
2 parents ad945d2 + b148470 commit de60354
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 12 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,13 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(bddisasm)

message(STATUS "Fetching kananlib (main)...")
message(STATUS "Fetching kananlib (b0323a0b005fc9e3944e0ea36dcc98eda4b84eea)...")
FetchContent_Declare(
kananlib
GIT_REPOSITORY
https://github.com/cursey/kananlib
GIT_TAG
main
b0323a0b005fc9e3944e0ea36dcc98eda4b84eea
)
FetchContent_MakeAvailable(kananlib)

Expand Down
2 changes: 1 addition & 1 deletion cmake.toml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ tag = "v1.34.10"

[fetch-content.kananlib]
git = "https://github.com/cursey/kananlib"
tag = "main"
tag = "b0323a0b005fc9e3944e0ea36dcc98eda4b84eea"

[target.utility]
type = "static"
Expand Down
1 change: 1 addition & 0 deletions shared/sdk/RETypeDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ sdk::RETypeDefinition* RETypeDB::find_type(std::string_view name) const {
}
}

std::unique_lock _{ g_tdb_type_mtx };
return g_tdb_type_map[name.data()];
}

Expand Down
10 changes: 8 additions & 2 deletions shared/sdk/RETypeDefinition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ sdk::RETypeDefinition* RETypeDefinition::get_underlying_type() const {
}
}

std::unique_lock _{ g_underlying_mtx };
return g_underlying_types[this];
#else
const auto value_field = this->get_field("value__");
Expand All @@ -391,6 +392,7 @@ sdk::RETypeDefinition* RETypeDefinition::get_underlying_type() const {

const auto underlying_type = value_field->get_type();

std::unique_lock _{ g_underlying_mtx };
g_underlying_types[this] = underlying_type;
return g_underlying_types[this];
#endif
Expand Down Expand Up @@ -438,6 +440,7 @@ sdk::REField* RETypeDefinition::get_field(std::string_view name) const {
}
}

std::unique_lock _{ g_field_mtx };
return g_field_map[full_name];
}

Expand Down Expand Up @@ -499,6 +502,7 @@ sdk::REMethodDefinition* RETypeDefinition::get_method(std::string_view name) con
}
}

std::unique_lock _{g_method_mtx};
return g_method_map[full_name];
}

Expand Down Expand Up @@ -934,6 +938,9 @@ ::REManagedObject* RETypeDefinition::get_runtime_type() const {
}
}
}

std::unique_lock _{g_runtime_type_mtx};
return g_runtime_type_map[this];
#else
auto vm = sdk::VM::get();

Expand All @@ -943,11 +950,10 @@ ::REManagedObject* RETypeDefinition::get_runtime_type() const {

const auto& vm_type = vm->types[this->get_index()];

std::unique_lock _{g_runtime_type_mtx};
g_runtime_type_map[this] = (::REManagedObject*)vm_type.runtime_type;
return g_runtime_type_map[this];
#endif

return g_runtime_type_map[this];
}

void* RETypeDefinition::get_instance() const {
Expand Down
74 changes: 71 additions & 3 deletions src/D3D12Hook.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#include <thread>
#include <future>
#include <unordered_set>
#include <stacktrace>

#include <spdlog/spdlog.h>
#include <utility/Thread.hpp>
#include <utility/Module.hpp>
#include <utility/String.hpp>
#include <utility/RTTI.hpp>

#include "REFramework.hpp"

Expand Down Expand Up @@ -224,6 +227,25 @@ bool D3D12Hook::hook() {
return false;
}

const auto ti = utility::rtti::get_type_info(swap_chain1);

try {
const auto swapchain_classname = ti != nullptr ? std::string_view{ti->name()} : "unknown";

if (swapchain_classname.contains("interposer::DXGISwapChain")) { // DLSS3
spdlog::info("Found Streamline (DLSSFG) swapchain during dummy initialization: {:x}", (uintptr_t)swap_chain1);
m_using_frame_generation_swapchain = true;
} else if (swapchain_classname.contains("FrameInterpolationSwapChain")) { // FSR3
spdlog::info("Found FSR3 swapchain during dummy initialization: {:x}", (uintptr_t)swap_chain1);
m_using_frame_generation_swapchain = true;
}
} catch (const std::exception& e) {
spdlog::error("Failed to get type info: {}", e.what());
} catch (...) {
spdlog::error("Failed to get type info: unknown exception");
}


spdlog::info("Finding command queue offset");

// Find the command queue offset in the swapchain
Expand All @@ -244,9 +266,13 @@ bool D3D12Hook::hook() {
}
}

auto target_swapchain = swap_chain;

// Scan throughout the swapchain for a valid pointer to scan through
// this is usually only necessary for Proton
if (m_command_queue_offset == 0) {
bool should_break = false;

for (auto base = 0; base < 512 * sizeof(void*); base += sizeof(void*)) {
const auto pre_scan_base = (uintptr_t)swap_chain1 + base;

Expand All @@ -271,17 +297,29 @@ bool D3D12Hook::hook() {
auto data = *(ID3D12CommandQueue**)pre_data;

if (data == command_queue) {
m_using_proton_swapchain = true;
// If we hook Streamline's Swapchain, the menu fails to render correctly/flickers
// So we switch out the swapchain with the internal one owned by Streamline
// Side note: Even though we are scanning for Proton here,
// this doubles as an offset scanner for the real swapchain inside Streamline (or FSR3)
if (m_using_frame_generation_swapchain) {
target_swapchain = (IDXGISwapChain3*)scan_base;
}

if (!m_using_frame_generation_swapchain) {
m_using_proton_swapchain = true;
}

m_command_queue_offset = i;
m_proton_swapchain_offset = base;
should_break = true;

spdlog::info("Proton potentially detected");
spdlog::info("Found command queue offset: {:x}", i);
break;
}
}

if (m_using_proton_swapchain) {
if (m_using_proton_swapchain || should_break) {
break;
}
}
Expand All @@ -302,7 +340,7 @@ bool D3D12Hook::hook() {

m_is_phase_1 = true;

auto& present_fn = (*(void***)swap_chain)[8]; // Present
auto& present_fn = (*(void***)target_swapchain)[8]; // Present
m_present_hook = std::make_unique<PointerHook>(&present_fn, (void*)&D3D12Hook::present);
m_hooked = true;
} catch (const std::exception& e) {
Expand Down Expand Up @@ -475,6 +513,21 @@ HRESULT WINAPI D3D12Hook::resize_buffers(IDXGISwapChain3* swap_chain, UINT buffe
spdlog::info("D3D12 resize buffers called");
spdlog::info(" Parameters: buffer_count {} width {} height {} new_format {} swap_chain_flags {}", buffer_count, width, height, new_format, swap_chain_flags);

// Walk the callstack and print out module names
try {
std::string callstack_str{};
for (const auto& entry : std::stacktrace::current()) {
//spdlog::info(" {}", entry.description());
callstack_str += entry.description() + "\n";
}

spdlog::info("callstack: \n{}", callstack_str); // because this can be running on a different thread and get garbled in the middle of the log
} catch (const std::exception& e) {
spdlog::error("Failed to print callstack: {}", e.what());
} catch(...) {
spdlog::error("Failed to print callstack: unknown exception");
}

auto d3d12 = g_d3d12_hook;
//auto& hook = d3d12->m_resize_buffers_hook;
//auto resize_buffers_fn = hook->get_original<decltype(D3D12Hook::resize_buffers)*>();
Expand Down Expand Up @@ -545,6 +598,21 @@ HRESULT WINAPI D3D12Hook::resize_target(IDXGISwapChain3* swap_chain, const DXGI_
spdlog::info("D3D12 resize target called");
spdlog::info(" Parameters: new_target_parameters {:x}", (uintptr_t)new_target_parameters);

// Walk the callstack and print out module names
try {
std::string callstack_str{};
for (const auto& entry : std::stacktrace::current()) {
//spdlog::info(" {}", entry.description());
callstack_str += entry.description() + "\n";
}

spdlog::info("callstack: \n{}", callstack_str); // because this can be running on a different thread and get garbled in the middle of the log
} catch (const std::exception& e) {
spdlog::error("Failed to print callstack: {}", e.what());
} catch(...) {
spdlog::error("Failed to print callstack: unknown exception");
}

auto d3d12 = g_d3d12_hook;
//auto resize_target_fn = d3d12->m_resize_target_hook->get_original<decltype(D3D12Hook::resize_target)*>();

Expand Down
5 changes: 5 additions & 0 deletions src/D3D12Hook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ class D3D12Hook
return m_using_proton_swapchain;
}

bool is_framegen_swapchain() const {
return m_using_frame_generation_swapchain;
}

void ignore_next_present() {
m_ignore_next_present = true;
}
Expand All @@ -108,6 +112,7 @@ class D3D12Hook
uint32_t m_proton_swapchain_offset{};

bool m_using_proton_swapchain{ false };
bool m_using_frame_generation_swapchain{ false };
bool m_hooked{ false };
bool m_is_phase_1{ true };
bool m_inside_present{false};
Expand Down
42 changes: 38 additions & 4 deletions src/REFramework.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ REFramework::REFramework(HMODULE reframework_module)
IntegrityCheckBypass::immediate_patch_re8();
#endif

#if defined(RE4) || defined(SF6)
#if defined(RE4) || defined(SF6) || TDB_VER >= 73
// Fixes new code added in RE4 only.
IntegrityCheckBypass::immediate_patch_re4();
#endif
Expand Down Expand Up @@ -662,6 +662,19 @@ void REFramework::on_frame_d3d12() {
return;
}

auto swapchain = m_d3d12_hook->get_swap_chain();
const auto bb_index = swapchain->GetCurrentBackBufferIndex();

// Test if our RT for this index is valid.
if (m_d3d12.get_rt((D3D12::RTV)bb_index) == nullptr) {
spdlog::error("RTV for index {} is null, reinitializing...", bb_index);
deinit_d3d12();
m_has_frame = false;
m_first_initialize = false;
m_initialized = false;
return;
}

cmd_ctx->wait(INFINITE);
{
std::scoped_lock _{ cmd_ctx->mtx };
Expand Down Expand Up @@ -692,8 +705,6 @@ void REFramework::on_frame_d3d12() {
cmd_ctx->cmd_list->ResourceBarrier(1, &barrier);

// Draw to the back buffer.
auto swapchain = m_d3d12_hook->get_swap_chain();
auto bb_index = swapchain->GetCurrentBackBufferIndex();
barrier.Transition.pResource = m_d3d12.rts[bb_index].Get();
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
Expand Down Expand Up @@ -1679,6 +1690,21 @@ bool REFramework::first_frame_initialize() {
m_mods_fully_initialized = true;
}

// Troubleshooting by logging loaded modules
// helps us figure out if someone has conflicting software running
try {
spdlog::info("Logging loaded modules...");

const auto loaded_modules = utility::get_loaded_module_names();

for (const auto& name : loaded_modules) {
spdlog::info("Loaded module: {}", utility::narrow(name));
}
} catch(...) {
spdlog::error("Failed to get loaded modules.");
}


return true;
}

Expand Down Expand Up @@ -1855,12 +1881,20 @@ bool REFramework::init_d3d12() {
if (SUCCEEDED(swapchain->GetBuffer(i, IID_PPV_ARGS(&m_d3d12.rts[i])))) {
device->CreateRenderTargetView(m_d3d12.rts[i].Get(), nullptr, m_d3d12.get_cpu_rtv(device, (D3D12::RTV)i));
} else {
spdlog::error("[D3D12] Failed to get back buffer for rtv.");
spdlog::error("[D3D12] Failed to get back buffer for rtv {}", i);
m_d3d12.rts[i].Reset(); // just in case
}
}

// Create our imgui and blank rts.
auto& backbuffer = m_d3d12.get_rt(D3D12::RTV::BACKBUFFER_0);

if (backbuffer == nullptr) {
spdlog::error("[D3D12] Failed to get first back buffer RTV.");
deinit_d3d12();
return false;
}

auto desc = backbuffer->GetDesc();

spdlog::info("[D3D12] Back buffer format is {}", desc.Format);
Expand Down
7 changes: 7 additions & 0 deletions src/WindowFilter.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <spdlog/spdlog.h>

#include "WindowFilter.hpp"

// To prevent usage of statics (TLS breaks the present thread...?)
Expand Down Expand Up @@ -27,6 +29,11 @@ WindowFilter::WindowFilter() {
std::scoped_lock _{m_mutex};

for (const auto hwnd : m_window_jobs) {
char window_name[256]{};
if (GetWindowTextA(hwnd, window_name, sizeof(window_name)) != 0) {
spdlog::info("[WindowFilter] Encountered new window: {}", window_name);
}

if (is_filtered_nocache(hwnd)) {
filter_window(hwnd);
}
Expand Down

0 comments on commit de60354

Please sign in to comment.