diff --git a/src/Features/Upscaling.cpp b/src/Features/Upscaling.cpp index 277ef2ba12..6907158552 100644 --- a/src/Features/Upscaling.cpp +++ b/src/Features/Upscaling.cpp @@ -204,7 +204,10 @@ void Upscaling::DrawSettings() } if (baseLabel) { - ImGui::SliderInt("Upscale Preset", (int*)&settings.qualityMode, 0, 4, baseLabel); + // Format the label with preset name and resolution scale + std::string labelWithScale = std::format("{} ( {:.2f}x )", baseLabel, (resolutionScale.x + resolutionScale.y) * 0.5f); + + ImGui::SliderInt("Upscale Preset", (int*)&settings.qualityMode, 0, 4, labelWithScale.c_str()); } if (upscaleMethod == UpscaleMethod::kFSR) { @@ -704,21 +707,28 @@ void Upscaling::ConfigureUpscaling(RE::BSGraphics::State* a_viewport) auto screenHeight = static_cast(screenSize.y); if (upscaleMethod != UpscaleMethod::kNONE && upscaleMethod != UpscaleMethod::kTAA) { - float resolutionScaleBase = 1.0f; + float2 resolutionScaleBase = { 1.0f, 1.0f }; if (globals::game::isVR) { - resolutionScaleBase = 1.0f; + resolutionScaleBase = { 1.0f, 1.0f }; } else if (upscaleMethod == UpscaleMethod::kDLSS) { resolutionScaleBase = streamline.GetInputResolutionScale((uint32_t)screenSize.x, (uint32_t)screenSize.y, settings.qualityMode); } else if (upscaleMethod == UpscaleMethod::kFSR) { resolutionScaleBase = fidelityFX.GetInputResolutionScale((uint32_t)screenSize.x, (uint32_t)screenSize.y, settings.qualityMode); } - auto renderWidth = static_cast(screenWidth * resolutionScaleBase); - auto renderHeight = static_cast(screenHeight * resolutionScaleBase); + auto renderWidth = static_cast(screenWidth * resolutionScaleBase.x); + auto renderHeight = static_cast(screenHeight * resolutionScaleBase.y); - resolutionScale.x = static_cast(renderWidth) / static_cast(screenWidth); - resolutionScale.y = static_cast(renderHeight) / static_cast(screenHeight); + // Use precise scale if the integer conversion doesn't change the dimensions + if (renderWidth == screenWidth && renderHeight == screenHeight) { + // For DLAA and other 1:1 modes, ensure exactly 1.0 + resolutionScale.x = 1.0f; + resolutionScale.y = 1.0f; + } else { + resolutionScale.x = static_cast(renderWidth) / static_cast(screenWidth); + resolutionScale.y = static_cast(renderHeight) / static_cast(screenHeight); + } auto phaseCount = GetJitterPhaseCount(renderWidth, screenWidth); diff --git a/src/Features/Upscaling/FidelityFX.cpp b/src/Features/Upscaling/FidelityFX.cpp index bb206037c7..e29e9ee20b 100644 --- a/src/Features/Upscaling/FidelityFX.cpp +++ b/src/Features/Upscaling/FidelityFX.cpp @@ -240,9 +240,10 @@ void FidelityFX::DestroyFSRResources() } } -float FidelityFX::GetInputResolutionScale([[maybe_unused]] uint32_t outputWidth, [[maybe_unused]] uint32_t outputHeight, uint32_t qualityMode) +float2 FidelityFX::GetInputResolutionScale([[maybe_unused]] uint32_t outputWidth, [[maybe_unused]] uint32_t outputHeight, uint32_t qualityMode) { - return 1.0f / ffxFsr3GetUpscaleRatioFromQualityMode((FfxFsr3QualityMode)qualityMode); + float scale = 1.0f / ffxFsr3GetUpscaleRatioFromQualityMode((FfxFsr3QualityMode)qualityMode); + return { scale, scale }; } FfxResource ffxGetResource(ID3D11Resource* dx11Resource, diff --git a/src/Features/Upscaling/FidelityFX.h b/src/Features/Upscaling/FidelityFX.h index 392c7d73c3..09930ad049 100644 --- a/src/Features/Upscaling/FidelityFX.h +++ b/src/Features/Upscaling/FidelityFX.h @@ -44,7 +44,7 @@ class FidelityFX void DestroyFSRResources(); - float GetInputResolutionScale(uint32_t outputWidth, uint32_t outputHeight, uint32_t qualityMode); + float2 GetInputResolutionScale(uint32_t outputWidth, uint32_t outputHeight, uint32_t qualityMode); void Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_reactiveMask, ID3D11Resource* a_transparencyCompositionMask, ID3D11Resource* a_motionVectors, float a_sharpness); diff --git a/src/Features/Upscaling/Streamline.cpp b/src/Features/Upscaling/Streamline.cpp index 536c39f8ed..23dbd79cb4 100644 --- a/src/Features/Upscaling/Streamline.cpp +++ b/src/Features/Upscaling/Streamline.cpp @@ -270,15 +270,8 @@ void Streamline::CheckFrameConstants() } } -void Streamline::Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_reactiveMask, ID3D11Resource* a_transparencyCompositionMask, ID3D11Resource* a_motionVectors) +void Streamline::SetDLSSOptions() { - CheckFrameConstants(); - - auto state = globals::state; - - auto renderer = globals::game::renderer; - auto& depthTexture = renderer->GetDepthStencilData().depthStencils[RE::RENDER_TARGETS_DEPTHSTENCIL::kMAIN]; - sl::DLSSOptions dlssOptions{}; // Map quality mode to DLSS mode @@ -301,6 +294,8 @@ void Streamline::Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_r break; } + auto state = globals::state; + dlssOptions.outputWidth = (uint)state->screenSize.x; dlssOptions.outputHeight = (uint)state->screenSize.y; dlssOptions.colorBuffersHDR = sl::Boolean::eTrue; @@ -318,6 +313,17 @@ void Streamline::Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_r if (SL_FAILED(result, slDLSSSetOptions(viewport, dlssOptions))) { logger::critical("[Streamline] Could not enable DLSS"); } +} + +void Streamline::Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_reactiveMask, ID3D11Resource* a_transparencyCompositionMask, ID3D11Resource* a_motionVectors) +{ + CheckFrameConstants(); + SetDLSSOptions(); + + auto state = globals::state; + + auto renderer = globals::game::renderer; + auto& depthTexture = renderer->GetDepthStencilData().depthStencils[RE::RENDER_TARGETS_DEPTHSTENCIL::kMAIN]; { auto screenSize = state->screenSize; @@ -352,7 +358,7 @@ void Streamline::Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_r slEvaluateFeature(sl::kFeatureDLSS, *frameToken, inputs, _countof(inputs), globals::d3d::context); } -float Streamline::GetInputResolutionScale(uint32_t outputWidth, uint32_t outputHeight, uint32_t qualityMode) +float2 Streamline::GetInputResolutionScale(uint32_t outputWidth, uint32_t outputHeight, uint32_t qualityMode) { sl::DLSSMode dlssMode; switch (qualityMode) { @@ -382,7 +388,7 @@ float Streamline::GetInputResolutionScale(uint32_t outputWidth, uint32_t outputH sl::Result result = slDLSSGetOptimalSettings(dlssOptions, optimalSettings); if (result != sl::Result::eOk) { logger::critical("[Streamline] Failed to get DLSS optimal settings, error code: {}", (int)result); - return 1.0f; + return { 1.0f, 1.0f }; } float scaleX; @@ -398,8 +404,8 @@ float Streamline::GetInputResolutionScale(uint32_t outputWidth, uint32_t outputH scaleY = (float)optimalSettings.optimalRenderHeight / (float)outputHeight; } - // Use the average scale (both should be the same for uniform scaling) - return (scaleX + scaleY) * 0.5f; + // Return separate X and Y scales for more precision + return { scaleX, scaleY }; } /** diff --git a/src/Features/Upscaling/Streamline.h b/src/Features/Upscaling/Streamline.h index 954a8a5bdb..d1a34184d9 100644 --- a/src/Features/Upscaling/Streamline.h +++ b/src/Features/Upscaling/Streamline.h @@ -80,9 +80,11 @@ class Streamline void CheckFrameConstants(); + void SetDLSSOptions(); + void Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_reactiveMask, ID3D11Resource* a_transparencyCompositionMask, ID3D11Resource* a_motionVectors); - float GetInputResolutionScale(uint32_t outputWidth, uint32_t outputHeight, uint32_t qualityPreset); + float2 GetInputResolutionScale(uint32_t outputWidth, uint32_t outputHeight, uint32_t qualityPreset); void DestroyDLSSResources();