Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion cmake/streamline.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
include(FetchContent)

string(REGEX MATCH "^v?([0-9]+)\\.([0-9]+)\\.([0-9]+)" STREAMLINE_VERSION_MATCH "${STREAMLINE_VERSION}")
if (STREAMLINE_VERSION_MATCH)
set(_STREAMLINE_VERSION_MAJOR "${CMAKE_MATCH_1}")
set(_STREAMLINE_VERSION_MINOR "${CMAKE_MATCH_2}")
set(_STREAMLINE_VERSION_PATCH "${CMAKE_MATCH_3}")
else()
set(_STREAMLINE_VERSION_MAJOR 2)
set(_STREAMLINE_VERSION_MINOR 4)
set(_STREAMLINE_VERSION_PATCH 2)
endif()

if (_STREAMLINE_VERSION_MAJOR LESS 2)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS STREAMLINE_LEGACY=1)
endif()

# Streamline - headers only
FetchContent_Declare(
streamline
Expand All @@ -8,4 +23,3 @@ FetchContent_Declare(
)
message("Fetching streamline ${STREAMLINE_VERSION}")
FetchContent_Populate(streamline)

49 changes: 28 additions & 21 deletions src/nvidia/UpscalerAfrNvidiaModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <experimental/DebugUtils.h>
#include <imgui.h>
#include <mods/VR.hpp>
#include <nvidia/streamline_compat.h>
#include <spdlog/spdlog.h>

std::optional<std::string> UpscalerAfrNvidiaModule::on_initialize()
Expand Down Expand Up @@ -90,13 +91,15 @@ void UpscalerAfrNvidiaModule::InstallHooks()
spdlog::error("Failed to hook slSetConstants");
}

using get_feature_funciton = sl::Result (*)(sl::Feature feature, const char* functionName, void*& function);
auto get_feature_function = (get_feature_funciton) GetProcAddress(p_hm_sl_interposter, "slGetFeatureFunction");
void* dlssSetOptionsFn;
get_feature_function(sl::kFeatureDLSS, "slDLSSSetOptions", dlssSetOptionsFn);
m_dlss_set_options_hook = std::make_unique<FunctionHook>((void**)dlssSetOptionsFn, (void*)&UpscalerAfrNvidiaModule::on_dlssSetOptions);
if (!m_dlss_set_options_hook->create()) {
spdlog::error("Failed to hook slSetOptions");
void* dlssSetOptionsFn = nullptr;
if (!slcompat::slCompatGetFeatureFunction(p_hm_sl_interposter, sl::kFeatureDLSS, "slDLSSSetOptions", dlssSetOptionsFn)) {
spdlog::error("Failed to find slDLSSSetOptions");
}
if (dlssSetOptionsFn) {
m_dlss_set_options_hook = std::make_unique<FunctionHook>((void**)dlssSetOptionsFn, (void*)&UpscalerAfrNvidiaModule::on_dlssSetOptions);
if (!m_dlss_set_options_hook->create()) {
spdlog::error("Failed to hook slSetOptions");
}
}
// void* slDLSSDSetOptionsFn;
// get_feature_function(sl::kFeatureDLSS_RR, "slDLSSDSetOptions", slDLSSDSetOptionsFn);
Expand All @@ -106,11 +109,15 @@ void UpscalerAfrNvidiaModule::InstallHooks()
// }

#ifdef STREAMLINE_DLSS_RR
void* slDLSSDSetOptionsFn;
get_feature_function(sl::kFeatureDLSS_RR, "slDLSSDSetOptions", slDLSSDSetOptionsFn);
m_dlssrr_set_options_hook = std::make_unique<FunctionHook>((void**)slDLSSDSetOptionsFn, (void*)&UpscalerAfrNvidiaModule::on_dlssrrSetOptions);
if (!m_dlssrr_set_options_hook->create()) {
spdlog::error("Failed to hook slDLSSDSetOptions");
void* slDLSSDSetOptionsFn = nullptr;
if (!slcompat::slCompatGetFeatureFunction(p_hm_sl_interposter, sl::kFeatureDLSS_RR, "slDLSSDSetOptions", slDLSSDSetOptionsFn)) {
spdlog::error("Failed to find slDLSSDSetOptions");
}
if (slDLSSDSetOptionsFn) {
m_dlssrr_set_options_hook = std::make_unique<FunctionHook>((void**)slDLSSDSetOptionsFn, (void*)&UpscalerAfrNvidiaModule::on_dlssrrSetOptions);
if (!m_dlssrr_set_options_hook->create()) {
spdlog::error("Failed to hook slDLSSDSetOptions");
}
}
#endif

Expand Down Expand Up @@ -198,15 +205,15 @@ void UpscalerAfrNvidiaModule::ReprojectMotionVectors(const sl::FrameToken& frame
sl::Result UpscalerAfrNvidiaModule::on_slSetTag(sl::ViewportHandle& viewport, const sl::ResourceTag* tags, uint32_t numTags, sl::CommandBuffer* cmdBuffer)
{
static auto instance = UpscalerAfrNvidiaModule::Get();
static auto original_fn = instance->m_set_tag_hook->get_original<decltype(UpscalerAfrNvidiaModule::on_slSetTag)>();
static auto original_fn = instance->m_set_tag_hook->get_original<slcompat::SlSetTagFn>();
static auto vr = VR::get();
// spdlog::error("UNEXPECTED CALL TO slSetTag");
// exit(1);
if(vr->m_render_frame_count % 2 == 0 && instance->m_enabled->value()) {
sl::ViewportHandle afr_viewport_handle{instance->m_afr_viewport_id};
return original_fn(afr_viewport_handle, tags, numTags, cmdBuffer);
return slcompat::slCompatSetTag(original_fn, afr_viewport_handle, tags, numTags, cmdBuffer);
}
auto result = original_fn(viewport, tags, numTags, cmdBuffer);
auto result = slcompat::slCompatSetTag(original_fn, viewport, tags, numTags, cmdBuffer);
return result;
}

Expand All @@ -225,7 +232,7 @@ namespace {
sl::Result UpscalerAfrNvidiaModule::on_slEvaluateFeature(sl::Feature feature, const sl::FrameToken& frame, sl::BaseStructure** inputs, uint32_t numInputs, sl::CommandBuffer* cmdBuffer)
{
static auto instance = UpscalerAfrNvidiaModule::Get();
static auto original_fn = instance->m_evaluate_feature_hook->get_original<decltype(UpscalerAfrNvidiaModule::on_slEvaluateFeature)>();
static auto original_fn = instance->m_evaluate_feature_hook->get_original<slcompat::SlEvaluateFeatureFn>();
static auto vr = VR::get();
//
// constexpr sl::BufferType kBufferTypeReactiveMaskHint = 36;
Expand Down Expand Up @@ -271,17 +278,17 @@ sl::Result UpscalerAfrNvidiaModule::on_slEvaluateFeature(sl::Feature feature, co
afr_inputs[i] = inputs[i];
}
}
return original_fn(feature, frame, afr_inputs.data(), numInputs, cmdBuffer);
return slcompat::slCompatEvaluateFeature(original_fn, feature, frame, afr_inputs.data(), numInputs, cmdBuffer);
}
auto result = original_fn(feature, frame, inputs, numInputs, cmdBuffer);
auto result = slcompat::slCompatEvaluateFeature(original_fn, feature, frame, inputs, numInputs, cmdBuffer);
return result;
}

// TODO vr->get_current_render_eye() == VRRuntime::Eye::RIGHT in real is left eye texture
sl::Result UpscalerAfrNvidiaModule::on_slSetConstants(sl::Constants& values, const sl::FrameToken& frame, sl::ViewportHandle& viewport)
{
static auto instance = UpscalerAfrNvidiaModule::Get();
static auto original_fn = instance->m_set_constants_hook->get_original<decltype(UpscalerAfrNvidiaModule::on_slSetConstants)>();
static auto original_fn = instance->m_set_constants_hook->get_original<slcompat::SlSetConstantsFn>();
#ifdef MOTION_VECTOR_REPROJECTION
instance->m_motion_vector_reprojection.m_mvecScale.x = values.mvecScale.x;
instance->m_motion_vector_reprojection.m_mvecScale.y = values.mvecScale.y;
Expand All @@ -296,9 +303,9 @@ sl::Result UpscalerAfrNvidiaModule::on_slSetConstants(sl::Constants& values, con

if(frame % 2 == 0 && instance->m_enabled->value()) {
sl::ViewportHandle afr_viewport_handle{instance->m_afr_viewport_id};
return original_fn(values, frame, afr_viewport_handle);
return slcompat::slCompatSetConstants(original_fn, values, frame, afr_viewport_handle);
}
auto result = original_fn(values, frame, viewport);
auto result = slcompat::slCompatSetConstants(original_fn, values, frame, viewport);
return result;
}

Expand Down
80 changes: 80 additions & 0 deletions src/nvidia/streamline_compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#pragma once

#include <sl.h>

#include <windows.h>

namespace slcompat {

#if defined(STREAMLINE_LEGACY)
#ifndef SL_STRUCT_TYPE_VIEWPORT
namespace sl {
struct ViewportHandle {
uint32_t id = 0;
};
} // namespace sl
#endif

#ifndef SL_STRUCT_TYPE_RESOURCE_TAG
namespace sl {
struct ResourceTag;
} // namespace sl
#endif

#ifndef SL_STRUCT_TYPE_FRAME_TOKEN
namespace sl {
using FrameToken = uint32_t;
} // namespace sl
#endif
#endif

#if defined(STREAMLINE_LEGACY)
using SlSetTagFn = sl::Result (*)(sl::ViewportHandle, const sl::ResourceTag*, uint32_t, sl::CommandBuffer*);
using SlEvaluateFeatureFn = sl::Result (*)(sl::Feature, const sl::FrameToken&, sl::BaseStructure* const*, uint32_t, sl::CommandBuffer*);
using SlSetConstantsFn = sl::Result (*)(sl::Constants*, const sl::FrameToken&, sl::ViewportHandle&);
#else
using SlSetTagFn = sl::Result (*)(sl::ViewportHandle&, const sl::ResourceTag*, uint32_t, sl::CommandBuffer*);
using SlEvaluateFeatureFn = sl::Result (*)(sl::Feature, const sl::FrameToken&, sl::BaseStructure**, uint32_t, sl::CommandBuffer*);
using SlSetConstantsFn = sl::Result (*)(sl::Constants&, const sl::FrameToken&, sl::ViewportHandle&);
#endif

inline bool slCompatGetFeatureFunction(HMODULE module, sl::Feature feature, const char* functionName, void*& function)
{
using GetFeatureFunctionFn = sl::Result (*)(sl::Feature, const char*, void*&);
auto get_feature_function = reinterpret_cast<GetFeatureFunctionFn>(GetProcAddress(module, "slGetFeatureFunction"));
if (get_feature_function) {
return get_feature_function(feature, functionName, function) == sl::Result::eOk;
}

function = reinterpret_cast<void*>(GetProcAddress(module, functionName));
return function != nullptr;
}

inline sl::Result slCompatSetTag(SlSetTagFn fn, sl::ViewportHandle& viewport, const sl::ResourceTag* tags, uint32_t numTags, sl::CommandBuffer* cmdBuffer)
{
#if defined(STREAMLINE_LEGACY)
return fn(viewport, tags, numTags, cmdBuffer);
#else
return fn(viewport, tags, numTags, cmdBuffer);
#endif
}

inline sl::Result slCompatEvaluateFeature(SlEvaluateFeatureFn fn, sl::Feature feature, const sl::FrameToken& frame, sl::BaseStructure** inputs, uint32_t numInputs, sl::CommandBuffer* cmdBuffer)
{
#if defined(STREAMLINE_LEGACY)
return fn(feature, frame, const_cast<sl::BaseStructure* const*>(inputs), numInputs, cmdBuffer);
#else
return fn(feature, frame, inputs, numInputs, cmdBuffer);
#endif
}

inline sl::Result slCompatSetConstants(SlSetConstantsFn fn, sl::Constants& values, const sl::FrameToken& frame, sl::ViewportHandle& viewport)
{
#if defined(STREAMLINE_LEGACY)
return fn(&values, frame, viewport);
#else
return fn(values, frame, viewport);
#endif
}

} // namespace slcompat