mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-09-23 05:46:27 +00:00
Fixes for SL inputs, incorrect resource size, invalid cmdlist, doubled slSetConstants, remove unnecessary hooks, fix sl dll override hooking
This commit is contained in:
@@ -21,10 +21,13 @@ bool Sl_Inputs_Dx12::setConstants(const sl::Constants& values, uint32_t frameId)
|
||||
|
||||
LOG_DEBUG("Setting consts for streamline index: {}", index);
|
||||
|
||||
// Streamline logs already log this
|
||||
// Streamline already log this error, keep using the previous data
|
||||
static uint32_t lastFrameId = UINT32_MAX;
|
||||
setConstantsSameFrameId = lastFrameId == frameId;
|
||||
lastFrameId = frameId;
|
||||
if (lastFrameId == frameId)
|
||||
{
|
||||
lastFrameId = frameId;
|
||||
return false;
|
||||
}
|
||||
|
||||
data = sl::Constants {};
|
||||
|
||||
@@ -147,8 +150,7 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: detect if there are multiple calls to hkslSetConstants with the same ID, DRG crashing, sl sees an error
|
||||
if (dispatched && !setConstantsSameFrameId)
|
||||
if (dispatched)
|
||||
{
|
||||
fgOutput->StartNewFrame();
|
||||
|
||||
@@ -167,23 +169,32 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo
|
||||
|
||||
hudlessSent = true;
|
||||
|
||||
// ResTrack_Dx12::SetHudlessCmdList(cmdBuffer);
|
||||
|
||||
auto hudlessResource = (ID3D12Resource*) tag.resource->native;
|
||||
|
||||
auto validity =
|
||||
(tag.lifecycle != sl::eOnlyValidNow) ? FG_ResourceValidity::UntilPresent : FG_ResourceValidity::ValidNow;
|
||||
|
||||
// We need to make sure we have a copy of hudless that WE can use
|
||||
if (cmdBuffer != nullptr && validity == FG_ResourceValidity::ValidNow)
|
||||
validity = FG_ResourceValidity::ValidButMakeCopy;
|
||||
// TODO: bugged and copy crashes
|
||||
// if (cmdBuffer != nullptr && validity == FG_ResourceValidity::ValidNow)
|
||||
// validity = FG_ResourceValidity::ValidButMakeCopy;
|
||||
|
||||
fgOutput->SetResource(FG_ResourceType::HudlessColor, cmdBuffer, hudlessResource, tag.extent.width,
|
||||
tag.extent.height, (D3D12_RESOURCE_STATES) tag.resource->state, validity);
|
||||
auto width = tag.extent.width;
|
||||
auto height = tag.extent.height;
|
||||
|
||||
if (!tag.extent)
|
||||
{
|
||||
const auto desc = hudlessResource->GetDesc();
|
||||
width = desc.Width;
|
||||
height = desc.Height;
|
||||
}
|
||||
|
||||
fgOutput->SetResource(FG_ResourceType::HudlessColor, cmdBuffer, hudlessResource, width, height,
|
||||
(D3D12_RESOURCE_STATES) tag.resource->state, validity);
|
||||
|
||||
// Assume hudless is the size used for interpolation
|
||||
interpolationWidth = tag.extent.width;
|
||||
interpolationHeight = tag.extent.height;
|
||||
interpolationWidth = width;
|
||||
interpolationHeight = height;
|
||||
|
||||
auto static lastFormat = DXGI_FORMAT_UNKNOWN;
|
||||
auto format = hudlessResource->GetDesc().Format;
|
||||
@@ -206,9 +217,20 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo
|
||||
|
||||
auto depthResource = (ID3D12Resource*) tag.resource->native;
|
||||
|
||||
auto width = tag.extent.width;
|
||||
auto height = tag.extent.height;
|
||||
|
||||
if (!tag.extent)
|
||||
{
|
||||
const auto desc = depthResource->GetDesc();
|
||||
width = desc.Width;
|
||||
height = desc.Height;
|
||||
}
|
||||
|
||||
const auto validity =
|
||||
(tag.lifecycle != sl::eOnlyValidNow) ? FG_ResourceValidity::UntilPresent : FG_ResourceValidity::ValidNow;
|
||||
fgOutput->SetResource(FG_ResourceType::Depth, cmdBuffer, depthResource, tag.extent.width, tag.extent.height,
|
||||
|
||||
fgOutput->SetResource(FG_ResourceType::Depth, cmdBuffer, depthResource, width, height,
|
||||
(D3D12_RESOURCE_STATES) tag.resource->state, validity);
|
||||
}
|
||||
else if (tag.type == sl::kBufferTypeMotionVectors)
|
||||
@@ -217,16 +239,25 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo
|
||||
|
||||
mvsSent = true;
|
||||
|
||||
mvsWidth = tag.extent.width;
|
||||
mvsHeight = tag.extent.height;
|
||||
|
||||
// ResTrack_Dx12::SetMVsCmdList(cmdBuffer);
|
||||
|
||||
auto mvResource = (ID3D12Resource*) tag.resource->native;
|
||||
|
||||
auto width = tag.extent.width;
|
||||
auto height = tag.extent.height;
|
||||
|
||||
if (!tag.extent)
|
||||
{
|
||||
const auto desc = mvResource->GetDesc();
|
||||
width = desc.Width;
|
||||
height = desc.Height;
|
||||
}
|
||||
|
||||
mvsWidth = width;
|
||||
mvsHeight = height;
|
||||
|
||||
const auto validity =
|
||||
(tag.lifecycle != sl::eOnlyValidNow) ? FG_ResourceValidity::UntilPresent : FG_ResourceValidity::ValidNow;
|
||||
fgOutput->SetResource(FG_ResourceType::Velocity, cmdBuffer, mvResource, tag.extent.width, tag.extent.height,
|
||||
|
||||
fgOutput->SetResource(FG_ResourceType::Velocity, cmdBuffer, mvResource, width, height,
|
||||
(D3D12_RESOURCE_STATES) tag.resource->state, validity);
|
||||
}
|
||||
else if (tag.type == sl::kBufferTypeUIColorAndAlpha)
|
||||
@@ -237,13 +268,22 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo
|
||||
|
||||
if (uiRequired)
|
||||
{
|
||||
// ResTrack_Dx12::SetUICmdList(cmdBuffer);
|
||||
|
||||
auto uiResource = (ID3D12Resource*) tag.resource->native;
|
||||
|
||||
auto width = tag.extent.width;
|
||||
auto height = tag.extent.height;
|
||||
|
||||
if (!tag.extent)
|
||||
{
|
||||
const auto desc = uiResource->GetDesc();
|
||||
width = desc.Width;
|
||||
height = desc.Height;
|
||||
}
|
||||
|
||||
const auto validity = (tag.lifecycle != sl::eOnlyValidNow) ? FG_ResourceValidity::UntilPresent
|
||||
: FG_ResourceValidity::ValidNow;
|
||||
fgOutput->SetResource(FG_ResourceType::UIColor, cmdBuffer, uiResource, tag.extent.width, tag.extent.height,
|
||||
|
||||
fgOutput->SetResource(FG_ResourceType::UIColor, cmdBuffer, uiResource, width, height,
|
||||
(D3D12_RESOURCE_STATES) tag.resource->state, validity);
|
||||
}
|
||||
}
|
||||
@@ -253,14 +293,23 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo
|
||||
|
||||
distortionFieldSent = true;
|
||||
|
||||
// ResTrack_Dx12::SetDistortionFieldCmdList(cmdBuffer);
|
||||
|
||||
auto distortionFieldResource = (ID3D12Resource*) tag.resource->native;
|
||||
|
||||
auto width = tag.extent.width;
|
||||
auto height = tag.extent.height;
|
||||
|
||||
if (!tag.extent)
|
||||
{
|
||||
const auto desc = distortionFieldResource->GetDesc();
|
||||
width = desc.Width;
|
||||
height = desc.Height;
|
||||
}
|
||||
|
||||
const auto validity =
|
||||
(tag.lifecycle != sl::eOnlyValidNow) ? FG_ResourceValidity::UntilPresent : FG_ResourceValidity::ValidNow;
|
||||
fgOutput->SetResource(FG_ResourceType::Distortion, cmdBuffer, distortionFieldResource, tag.extent.width,
|
||||
tag.extent.height, (D3D12_RESOURCE_STATES) tag.resource->state, validity);
|
||||
|
||||
fgOutput->SetResource(FG_ResourceType::Distortion, cmdBuffer, distortionFieldResource, width, height,
|
||||
(D3D12_RESOURCE_STATES) tag.resource->state, validity);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -366,8 +415,7 @@ bool Sl_Inputs_Dx12::dispatchFG()
|
||||
|
||||
// Streamline is not 100% clear on if we should multiply by resolution or not.
|
||||
// But UE games and Dead Rising expect that multiplication to be done, even if the scale is 1.0.
|
||||
// bool multiplyByResolution = dataCopy.mvecScale.x != 1.f || dataCopy.mvecScale.y
|
||||
// != 1.f;
|
||||
// bool multiplyByResolution = dataCopy.mvecScale.x != 1.f || dataCopy.mvecScale.y != 1.f;
|
||||
bool multiplyByResolution = true;
|
||||
if (multiplyByResolution)
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@ class Sl_Inputs_Dx12
|
||||
std::optional<sl::Constants> slConstants[BUFFER_COUNT] {};
|
||||
sl::EngineType engineType = sl::EngineType::eCount;
|
||||
|
||||
// TODO: make "sent" map/array
|
||||
bool depthSent = false;
|
||||
bool hudlessSent = false;
|
||||
bool mvsSent = false;
|
||||
@@ -21,7 +22,6 @@ class Sl_Inputs_Dx12
|
||||
bool distortionFieldRequired = false;
|
||||
|
||||
bool dispatched = false;
|
||||
bool setConstantsSameFrameId = false;
|
||||
|
||||
bool frameBasedTracking = false;
|
||||
uint32_t indexToFrameIdMapping[BUFFER_COUNT] {};
|
||||
|
||||
@@ -658,10 +658,16 @@ void XeFG_Dx12::SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cmd
|
||||
|
||||
xefg_swapchain_d3d12_resource_data_t resourceParam = GetResourceData(type);
|
||||
|
||||
// HACK: XeFG docs lie and cmd list is technically required as it checks for it
|
||||
// But it doesn't seem to use it when the validity is UNTIL_NEXT_PRESENT
|
||||
if (cmdList == nullptr && resourceParam.validity == XEFG_SWAPCHAIN_RV_UNTIL_NEXT_PRESENT)
|
||||
cmdList = (ID3D12GraphicsCommandList*) 1;
|
||||
|
||||
auto result = XeFGProxy::D3D12TagFrameResource()(_swapChainContext, cmdList, _frameCount, &resourceParam);
|
||||
if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("D3D12TagFrameResource Depth error: {} ({})", magic_enum::enum_name(result), (UINT) result);
|
||||
LOG_ERROR("D3D12TagFrameResource {} error: {} ({})", magic_enum::enum_name(type), magic_enum::enum_name(result),
|
||||
(UINT) result);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -217,8 +217,6 @@ static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags)
|
||||
LOG_DEBUG("_frameCounter: {}, flags: {:X}, Frametime: {}", _frameCounter, Flags, ftDelta);
|
||||
}
|
||||
|
||||
IFGFeature_Dx12* fg = State::Instance().currentFG;
|
||||
|
||||
if (willPresent)
|
||||
{
|
||||
if (State::Instance().activeFgInput == FGInput::Upscaler && HooksDx::dx12UpscaleTrig &&
|
||||
@@ -257,11 +255,14 @@ static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags)
|
||||
HooksDx::readbackBuffer->Unmap(0, nullptr);
|
||||
HooksDx::dx12UpscaleTrig = false;
|
||||
}
|
||||
|
||||
if (State::Instance().slFGInputs.readyForDispatch() && !State::Instance().slFGInputs.dispatchFG())
|
||||
LOG_DEBUG("Streamline FG was not dispatched");
|
||||
|
||||
State::Instance().slFGInputs.markLastSendAsRequired();
|
||||
}
|
||||
|
||||
if (State::Instance().slFGInputs.readyForDispatch())
|
||||
State::Instance().slFGInputs.dispatchFG();
|
||||
|
||||
IFGFeature_Dx12* fg = State::Instance().currentFG;
|
||||
bool mutexUsed = false;
|
||||
if (willPresent && fg != nullptr && fg->IsActive() &&
|
||||
Config::Instance()->FGUseMutexForSwapchain.value_or_default() && fg->Mutex.getOwner() != 2)
|
||||
@@ -277,14 +278,6 @@ static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags)
|
||||
fg->Present();
|
||||
}
|
||||
|
||||
State::Instance().slFGInputs.markLastSendAsRequired();
|
||||
|
||||
// if (willPresent && State::Instance().activeFgInput == FGInput::DLSSG &&
|
||||
// State::Instance().slFGInputs.readyForDispatch() && fg != nullptr)
|
||||
//{
|
||||
// State::Instance().slFGInputs.dispatchFG(nullptr);
|
||||
// }
|
||||
|
||||
if (willPresent)
|
||||
{
|
||||
ResTrack_Dx12::ClearPossibleHudless();
|
||||
@@ -310,7 +303,7 @@ static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags)
|
||||
|
||||
Hudfix_Dx12::PresentEnd();
|
||||
|
||||
if (!State::Instance().reflexLimitsFps && State::Instance().activeFgOutput != FGOutput::NoFG)
|
||||
if (willPresent && !State::Instance().reflexLimitsFps && State::Instance().activeFgOutput != FGOutput::NoFG)
|
||||
FrameLimit::sleep(fg != nullptr ? fg->IsActive() : false);
|
||||
|
||||
if (mutexUsed && fg != nullptr)
|
||||
|
||||
@@ -621,7 +621,7 @@ class KernelHooks
|
||||
// Try to catch something like this:
|
||||
// C:\ProgramData/NVIDIA/NGX/models/sl_dlss_0/versions/133120/files/190_E658703.dll
|
||||
if (CheckDllNameW(&lcaseLibName, &slDlssNamesW) ||
|
||||
(lcaseLibName.contains(L"/versions/") && lcaseLibName.contains(L"/sl_dlss_")))
|
||||
(lcaseLibName.contains(L"/versions/") && lcaseLibName.contains(L"/sl_dlss_0")))
|
||||
{
|
||||
auto dlssModule = KernelBaseProxy::LoadLibraryExW_()(lpLibFullPath, NULL, 0);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "include/sl.param/parameters.h"
|
||||
|
||||
sl::RenderAPI StreamlineHooks::renderApi = sl::RenderAPI::eCount;
|
||||
std::mutex StreamlineHooks::setConstantsMutex {};
|
||||
|
||||
// interposer
|
||||
decltype(&slInit) StreamlineHooks::o_slInit = nullptr;
|
||||
@@ -128,7 +129,7 @@ sl::Result StreamlineHooks::hkslSetTag(sl::ViewportHandle& viewport, sl::Resourc
|
||||
|
||||
for (uint32_t i = 0; i < numTags; i++)
|
||||
{
|
||||
if (tags[i].resource == nullptr)
|
||||
if (tags[i].resource == nullptr || tags[i].resource->native == nullptr)
|
||||
{
|
||||
LOG_TRACE("Resource of type: {} is null, continuing", tags[i].type);
|
||||
continue;
|
||||
@@ -414,9 +415,8 @@ bool StreamlineHooks::hkdlssg_slOnPluginLoad(void* params, const char* loaderJSO
|
||||
sl::Result StreamlineHooks::hkslSetConstants(const sl::Constants& values, const sl::FrameToken& frame,
|
||||
const sl::ViewportHandle& viewport)
|
||||
{
|
||||
unsigned int frameIndex = frame;
|
||||
|
||||
LOG_TRACE("called with frameIndex: {}", frameIndex);
|
||||
std::scoped_lock lock(setConstantsMutex);
|
||||
LOG_TRACE("called with frameIndex: {}, viewport: {}", (unsigned int) frame, (unsigned int) viewport);
|
||||
|
||||
State::Instance().slFGInputs.setConstants(values, (uint32_t) frame);
|
||||
|
||||
@@ -426,8 +426,25 @@ sl::Result StreamlineHooks::hkslSetConstants(const sl::Constants& values, const
|
||||
bool StreamlineHooks::hkcommon_slOnPluginLoad(void* params, const char* loaderJSON, const char** pluginJSON)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
// TODO: do it better than "static" and hoping for the best
|
||||
static std::string config;
|
||||
|
||||
auto result = o_common_slOnPluginLoad(params, loaderJSON, pluginJSON);
|
||||
|
||||
// Completely disables Streamline hooks
|
||||
// if (true)
|
||||
//{
|
||||
// nlohmann::json configJson = nlohmann::json::parse(*pluginJSON);
|
||||
|
||||
// configJson["hooks"].clear();
|
||||
// configJson["exclusive_hooks"].clear();
|
||||
|
||||
// config = configJson.dump();
|
||||
|
||||
// *pluginJSON = config.c_str();
|
||||
//}
|
||||
|
||||
if (Config::Instance()->StreamlineSpoofing.value_or_default())
|
||||
setSystemCapsArch((sl::param::IParameters*) params, UINT_MAX);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ class StreamlineHooks
|
||||
|
||||
private:
|
||||
static sl::RenderAPI renderApi;
|
||||
static std::mutex setConstantsMutex;
|
||||
|
||||
// Interposer
|
||||
static decltype(&slInit) o_slInit;
|
||||
|
||||
@@ -1820,7 +1820,7 @@ void ResTrack_Dx12::HookDevice(ID3D12Device* device)
|
||||
o_CopyDescriptorsSimple = (PFN_CopyDescriptorsSimple) pVTable[24];
|
||||
|
||||
// Apply the detour
|
||||
if (o_CreateDescriptorHeap != nullptr)
|
||||
if (o_CreateDescriptorHeap != nullptr && State::Instance().activeFgInput == FGInput::Upscaler)
|
||||
{
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
@@ -318,7 +318,7 @@ bool HC_Dx12::Dispatch(IDXGISwapChain3* sc, ID3D12CommandQueue* queue, ID3D12Res
|
||||
// Check Hudless Buffer
|
||||
D3D12_RESOURCE_DESC hudlessDesc = hudless->GetDesc();
|
||||
|
||||
if (hudlessDesc.Format != scDesc.BufferDesc.Format || hudlessDesc.Width != scDesc.BufferDesc.Width ||
|
||||
if (/*hudlessDesc.Format != scDesc.BufferDesc.Format ||*/ hudlessDesc.Width != scDesc.BufferDesc.Width ||
|
||||
hudlessDesc.Height != scDesc.BufferDesc.Height)
|
||||
{
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user