diff --git a/cmake/streamline.cmake b/cmake/streamline.cmake index 56e6ccc..5cae412 100644 --- a/cmake/streamline.cmake +++ b/cmake/streamline.cmake @@ -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 @@ -8,4 +23,3 @@ FetchContent_Declare( ) message("Fetching streamline ${STREAMLINE_VERSION}") FetchContent_Populate(streamline) - diff --git a/src/nvidia/UpscalerAfrNvidiaModule.cpp b/src/nvidia/UpscalerAfrNvidiaModule.cpp index 3357204..8d2ec2a 100644 --- a/src/nvidia/UpscalerAfrNvidiaModule.cpp +++ b/src/nvidia/UpscalerAfrNvidiaModule.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include std::optional UpscalerAfrNvidiaModule::on_initialize() @@ -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((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((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); @@ -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((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((void**)slDLSSDSetOptionsFn, (void*)&UpscalerAfrNvidiaModule::on_dlssrrSetOptions); + if (!m_dlssrr_set_options_hook->create()) { + spdlog::error("Failed to hook slDLSSDSetOptions"); + } } #endif @@ -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(); + static auto original_fn = instance->m_set_tag_hook->get_original(); 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; } @@ -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(); + static auto original_fn = instance->m_evaluate_feature_hook->get_original(); static auto vr = VR::get(); // // constexpr sl::BufferType kBufferTypeReactiveMaskHint = 36; @@ -271,9 +278,9 @@ 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; } @@ -281,7 +288,7 @@ sl::Result UpscalerAfrNvidiaModule::on_slEvaluateFeature(sl::Feature feature, co 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(); + static auto original_fn = instance->m_set_constants_hook->get_original(); #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; @@ -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; } diff --git a/src/nvidia/streamline_compat.h b/src/nvidia/streamline_compat.h new file mode 100644 index 0000000..ca67b3d --- /dev/null +++ b/src/nvidia/streamline_compat.h @@ -0,0 +1,80 @@ +#pragma once + +#include + +#include + +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(GetProcAddress(module, "slGetFeatureFunction")); + if (get_feature_function) { + return get_feature_function(feature, functionName, function) == sl::Result::eOk; + } + + function = reinterpret_cast(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(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