Skip to content

Commit 5828c61

Browse files
feat(upscaling): sharpening slider (#1527)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 2ea3b3a commit 5828c61

File tree

10 files changed

+153
-56
lines changed

10 files changed

+153
-56
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
[Info]
2-
Version = 1-0-0
2+
Version = 1-1-0
944 KB
Binary file not shown.

features/Upscaling/Shaders/Upscaling/XeSS/LICENSE.txt

Lines changed: 0 additions & 27 deletions
This file was deleted.
-74.2 MB
Binary file not shown.

src/Features/Upscaling.cpp

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(
1515
Upscaling::Settings,
1616
upscaleMethod,
17+
upscaleMethodNoDLSS,
1718
qualityMode,
1819
frameLimitMode,
1920
frameGenerationMode,
@@ -166,6 +167,8 @@ void Upscaling::DrawSettings()
166167
availableModes = 2; // Add FSR
167168
if (featureDLSS)
168169
availableModes = 3; // Add DLSS if available
170+
else
171+
currentUpscaleMode = &settings.upscaleMethodNoDLSS;
169172

170173
// Slider for method selection
171174
// Clamp the index used to read from the built label vector to avoid OOB if the stored value is stale
@@ -203,6 +206,12 @@ void Upscaling::DrawSettings()
203206
if (baseLabel) {
204207
ImGui::SliderInt("Upscale Preset", (int*)&settings.qualityMode, 0, 4, baseLabel);
205208
}
209+
210+
if (upscaleMethod == UpscaleMethod::kFSR) {
211+
ImGui::SliderFloat("Sharpness", &settings.sharpnessFSR, 0.0f, 1.0f, "%.1f");
212+
} else if (upscaleMethod == UpscaleMethod::kDLSS) {
213+
ImGui::SliderFloat("Sharpness", &settings.sharpnessDLSS, 0.0f, 1.0f, "%.1f");
214+
}
206215
}
207216
} else {
208217
ImGui::Text("Upscaling from lower resolutions is not currently available for VR");
@@ -415,28 +424,28 @@ void Upscaling::PostPostLoad()
415424

416425
Upscaling::UpscaleMethod Upscaling::GetUpscaleMethod()
417426
{
418-
settings.upscaleMethod = std::clamp(settings.upscaleMethod, (uint)UpscaleMethod::kNONE, (uint)UpscaleMethod::kDLSS);
419-
settings.qualityMode = std::clamp(settings.qualityMode, 0u, 4u);
420-
return (UpscaleMethod)settings.upscaleMethod;
427+
if (streamline.featureDLSS)
428+
return (UpscaleMethod)settings.upscaleMethod;
429+
return (UpscaleMethod)settings.upscaleMethodNoDLSS;
421430
}
422431

423432
void Upscaling::CreateUpscalingTextureResources(UpscaleMethod a_upscalemethod)
424433
{
425434
logger::debug("[Upscaling] Creating texture resources for method {}", (int)a_upscalemethod);
426435

427-
if (a_upscalemethod == UpscaleMethod::kDLSS || a_upscalemethod == UpscaleMethod::kFSR) {
428-
auto renderer = globals::game::renderer;
429-
auto& main = renderer->GetRuntimeData().renderTargets[RE::RENDER_TARGETS::kMAIN];
436+
auto renderer = globals::game::renderer;
437+
auto& main = renderer->GetRuntimeData().renderTargets[RE::RENDER_TARGETS::kMAIN];
430438

431-
D3D11_TEXTURE2D_DESC texDesc{};
432-
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
433-
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
439+
D3D11_TEXTURE2D_DESC texDesc{};
440+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
441+
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
442+
main.texture->GetDesc(&texDesc);
443+
main.SRV->GetDesc(&srvDesc);
444+
main.UAV->GetDesc(&uavDesc);
434445

435-
main.texture->GetDesc(&texDesc);
436-
main.SRV->GetDesc(&srvDesc);
437-
main.UAV->GetDesc(&uavDesc);
446+
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
438447

439-
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
448+
if (a_upscalemethod == UpscaleMethod::kDLSS || a_upscalemethod == UpscaleMethod::kFSR) {
440449
texDesc.Format = DXGI_FORMAT_R8_UNORM;
441450
srvDesc.Format = texDesc.Format;
442451
uavDesc.Format = texDesc.Format;
@@ -457,24 +466,29 @@ void Upscaling::CreateUpscalingTextureResources(UpscaleMethod a_upscalemethod)
457466
// Motion vector copy texture is only needed for DLSS
458467
if (a_upscalemethod == UpscaleMethod::kDLSS) {
459468
if (!motionVectorCopyTexture) {
460-
auto renderer = globals::game::renderer;
461469
auto& motionVector = renderer->GetRuntimeData().renderTargets[RE::RENDER_TARGETS::kMOTION_VECTOR];
462470

463471
D3D11_TEXTURE2D_DESC motionTexDesc{};
464-
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
465-
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
466-
467472
motionVector.texture->GetDesc(&motionTexDesc);
468-
motionVector.SRV->GetDesc(&srvDesc);
469-
motionVector.UAV->GetDesc(&uavDesc);
470473

471-
srvDesc.Format = motionTexDesc.Format;
472-
uavDesc.Format = motionTexDesc.Format;
474+
texDesc.Format = motionTexDesc.Format;
475+
srvDesc.Format = texDesc.Format;
476+
uavDesc.Format = texDesc.Format;
473477

474478
motionVectorCopyTexture = new Texture2D(motionTexDesc);
475479
motionVectorCopyTexture->CreateSRV(srvDesc);
476480
motionVectorCopyTexture->CreateUAV(uavDesc);
477481
}
482+
483+
if (!nisSharpenerTexture) {
484+
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
485+
srvDesc.Format = texDesc.Format;
486+
uavDesc.Format = texDesc.Format;
487+
488+
nisSharpenerTexture = new Texture2D(texDesc);
489+
nisSharpenerTexture->CreateSRV(srvDesc);
490+
nisSharpenerTexture->CreateUAV(uavDesc);
491+
}
478492
}
479493
}
480494

@@ -514,6 +528,14 @@ void Upscaling::DestroyUpscalingTextureResources(UpscaleMethod a_upscalemethod)
514528
delete motionVectorCopyTexture;
515529
motionVectorCopyTexture = nullptr;
516530
}
531+
if (nisSharpenerTexture) {
532+
nisSharpenerTexture->srv = nullptr;
533+
nisSharpenerTexture->uav = nullptr;
534+
nisSharpenerTexture->resource = nullptr;
535+
536+
delete nisSharpenerTexture;
537+
nisSharpenerTexture = nullptr;
538+
}
517539
}
518540
}
519541

@@ -1196,7 +1218,7 @@ void Upscaling::Upscale()
11961218
if (upscaleMethod == UpscaleMethod::kDLSS) {
11971219
streamline.Upscale(main.texture, reactiveMaskTexture->resource.get(), transparencyCompositionMaskTexture->resource.get(), motionVectorCopyTexture->resource.get());
11981220
} else if (upscaleMethod == UpscaleMethod::kFSR) {
1199-
fidelityFX.Upscale(main.texture, reactiveMaskTexture->resource.get(), transparencyCompositionMaskTexture->resource.get(), motionVector.texture);
1221+
fidelityFX.Upscale(main.texture, reactiveMaskTexture->resource.get(), transparencyCompositionMaskTexture->resource.get(), motionVector.texture, settings.sharpnessFSR);
12001222
}
12011223

12021224
state->EndPerfEvent();
@@ -1328,6 +1350,34 @@ void Upscaling::UpscaleDepth()
13281350
}
13291351
}
13301352

1353+
void Upscaling::ApplyNISSharpening()
1354+
{
1355+
if (!streamline.featureNIS || settings.sharpnessDLSS <= 0.0f) {
1356+
return;
1357+
}
1358+
1359+
auto context = globals::d3d::context;
1360+
1361+
ID3D11RenderTargetView* renderTarget = nullptr;
1362+
context->OMGetRenderTargets(1, &renderTarget, nullptr);
1363+
1364+
winrt::com_ptr<ID3D11Resource> mainResource;
1365+
renderTarget->GetResource(mainResource.put());
1366+
1367+
context->OMSetRenderTargets(0, nullptr, nullptr); // Unbind all bound render targets
1368+
1369+
context->CopyResource(nisSharpenerTexture->resource.get(), mainResource.get());
1370+
1371+
streamline.ApplyNISSharpening(nisSharpenerTexture->resource.get(), settings.sharpnessDLSS);
1372+
1373+
context->CopyResource(mainResource.get(), nisSharpenerTexture->resource.get());
1374+
1375+
globals::game::stateUpdateFlags->set(RE::BSGraphics::ShaderFlags::DIRTY_RENDERTARGET); // Run OMSetRenderTargets again
1376+
1377+
if (renderTarget)
1378+
renderTarget->Release();
1379+
}
1380+
13311381
void Upscaling::Main_UpdateJitter::thunk(RE::BSGraphics::State* a_state)
13321382
{
13331383
globals::features::upscaling.ConfigureTAA();
@@ -1359,6 +1409,9 @@ void Upscaling::Main_PostProcessing::thunk(RE::ImageSpaceManager* a1, uint32_t a
13591409

13601410
func(a1, a3, er8_);
13611411

1412+
if (upscaleMethod == UpscaleMethod::kDLSS)
1413+
upscaling.ApplyNISSharpening();
1414+
13621415
// Disable TAA in some menus
13631416
BSImagespaceShaderISTemporalAA->taaEnabled = false;
13641417
}

src/Features/Upscaling.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,15 @@ struct Upscaling : Feature
4848

4949
struct Settings
5050
{
51-
uint upscaleMethod = (uint)UpscaleMethod::kTAA;
51+
uint upscaleMethod = (uint)UpscaleMethod::kDLSS;
52+
uint upscaleMethodNoDLSS = (uint)UpscaleMethod::kFSR;
5253
uint qualityMode = 1; // Default to Quality (1=Quality, 2=Balanced, 3=Performance, 4=Ultra Performance, 0=Native AA)
5354
uint frameLimitMode = 1;
5455
uint frameGenerationMode = 1;
5556
uint frameGenerationForceEnable = 0;
5657
uint streamlineLogLevel = 0; // 0=Off, 1=Default, 2=Verbose
58+
float sharpnessFSR = 1.0f;
59+
float sharpnessDLSS = 0.1f;
5760
};
5861

5962
Settings settings;
@@ -134,6 +137,7 @@ struct Upscaling : Feature
134137
Texture2D* reactiveMaskTexture = nullptr;
135138
Texture2D* transparencyCompositionMaskTexture = nullptr;
136139
Texture2D* motionVectorCopyTexture = nullptr;
140+
Texture2D* nisSharpenerTexture = nullptr;
137141

138142
virtual void ClearShaderCache() override;
139143

@@ -155,6 +159,8 @@ struct Upscaling : Feature
155159
void PerformUpscaling();
156160
void UpscaleDepth();
157161

162+
void ApplyNISSharpening();
163+
158164
static void TimerSleepQPC(int64_t targetQPC);
159165

160166
void FrameLimiter();

src/Features/Upscaling/FidelityFX.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ FfxResource ffxGetResource(ID3D11Resource* dx11Resource,
263263
return resource;
264264
}
265265

266-
void FidelityFX::Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_reactiveMask, ID3D11Resource* a_transparencyCompositionMask, ID3D11Resource* a_motionVectors)
266+
void FidelityFX::Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_reactiveMask, ID3D11Resource* a_transparencyCompositionMask, ID3D11Resource* a_motionVectors, float a_sharpness)
267267
{
268268
auto renderer = globals::game::renderer;
269269
auto context = globals::d3d::context;
@@ -302,7 +302,7 @@ void FidelityFX::Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_r
302302
dispatchParameters.cameraNear = *globals::game::cameraNear;
303303

304304
dispatchParameters.enableSharpening = true;
305-
dispatchParameters.sharpness = 0.0f;
305+
dispatchParameters.sharpness = a_sharpness;
306306

307307
dispatchParameters.cameraFovAngleVertical = Util::GetVerticalFOVRad();
308308
dispatchParameters.viewSpaceToMetersFactor = 0.01428222656f;

src/Features/Upscaling/FidelityFX.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class FidelityFX
4646

4747
float GetInputResolutionScale(uint32_t outputWidth, uint32_t outputHeight, uint32_t qualityMode);
4848

49-
void Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_reactiveMask, ID3D11Resource* a_transparencyCompositionMask, ID3D11Resource* a_motionVectors);
49+
void Upscale(ID3D11Resource* a_upscalingTexture, ID3D11Resource* a_reactiveMask, ID3D11Resource* a_transparencyCompositionMask, ID3D11Resource* a_motionVectors, float a_sharpness);
5050

5151
private:
5252
// FSR scratch buffer - needs to be freed in DestroyFSRResources

src/Features/Upscaling/Streamline.cpp

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ void Streamline::LoadInterposer()
102102

103103
sl::Preferences pref;
104104

105-
sl::Feature featuresToLoad[] = { sl::kFeatureDLSS };
106-
sl::Feature featuresToLoadVR[] = { sl::kFeatureDLSS };
105+
sl::Feature featuresToLoad[] = { sl::kFeatureDLSS, sl::kFeatureNIS };
106+
sl::Feature featuresToLoadVR[] = { sl::kFeatureDLSS, sl::kFeatureNIS };
107107

108108
pref.featuresToLoad = REL::Module::IsVR() ? featuresToLoadVR : featuresToLoad;
109109
pref.numFeaturesToLoad = REL::Module::IsVR() ? _countof(featuresToLoadVR) : _countof(featuresToLoad);
@@ -181,7 +181,21 @@ void Streamline::CheckFeatures(IDXGIAdapter* a_adapter)
181181
}
182182
}
183183

184+
slIsFeatureLoaded(sl::kFeatureNIS, featureNIS);
185+
if (featureNIS) {
186+
logger::info("[Streamline] NIS feature is loaded");
187+
featureNIS = slIsFeatureSupported(sl::kFeatureNIS, adapterInfo) == sl::Result::eOk;
188+
} else {
189+
logger::info("[Streamline] NIS feature is not loaded");
190+
sl::FeatureRequirements featureRequirements;
191+
sl::Result result = slGetFeatureRequirements(sl::kFeatureNIS, featureRequirements);
192+
if (result != sl::Result::eOk) {
193+
logger::info("[Streamline] NIS feature failed to load due to: {}", magic_enum::enum_name(result));
194+
}
195+
}
196+
184197
logger::info("[Streamline] DLSS {} available", featureDLSS ? "is" : "is not");
198+
logger::info("[Streamline] NIS {} available", featureNIS ? "is" : "is not");
185199
}
186200

187201
void Streamline::PostDevice()
@@ -193,6 +207,11 @@ void Streamline::PostDevice()
193207
slGetFeatureFunction(sl::kFeatureDLSS, "slDLSSGetState", (void*&)slDLSSGetState);
194208
slGetFeatureFunction(sl::kFeatureDLSS, "slDLSSSetOptions", (void*&)slDLSSSetOptions);
195209
}
210+
211+
if (featureNIS) {
212+
slGetFeatureFunction(sl::kFeatureNIS, "slNISSetOptions", (void*&)slNISSetOptions);
213+
slGetFeatureFunction(sl::kFeatureNIS, "slNISGetState", (void*&)slNISGetState);
214+
}
196215
}
197216

198217
/**
@@ -394,4 +413,42 @@ void Streamline::DestroyDLSSResources()
394413
dlssOptions.mode = sl::DLSSMode::eOff;
395414
slDLSSSetOptions(viewport, dlssOptions);
396415
slFreeResources(sl::kFeatureDLSS, viewport);
416+
}
417+
418+
void Streamline::ApplyNISSharpening(ID3D11Resource* a_texture, float sharpness)
419+
{
420+
if (!featureNIS) {
421+
return;
422+
}
423+
424+
CheckFrameConstants();
425+
426+
sl::NISOptions nisOptions{};
427+
nisOptions.mode = sl::NISMode::eSharpen;
428+
nisOptions.sharpness = std::clamp(sharpness, 0.0f, 1.0f);
429+
nisOptions.hdrMode = sl::NISHDR::eNone;
430+
431+
if (SL_FAILED(result, slNISSetOptions(viewport, nisOptions))) {
432+
logger::error("[Streamline] Could not set NIS options");
433+
return;
434+
}
435+
436+
auto state = globals::state;
437+
sl::Extent fullExtent{ 0, 0, (uint)state->screenSize.x, (uint)state->screenSize.y };
438+
439+
sl::Resource colorIn = { sl::ResourceType::eTex2d, a_texture, 0 };
440+
sl::Resource colorOut = { sl::ResourceType::eTex2d, a_texture, 0 };
441+
442+
sl::ResourceTag colorInTag = sl::ResourceTag{ &colorIn, sl::kBufferTypeScalingInputColor, sl::ResourceLifecycle::eOnlyValidNow, &fullExtent };
443+
sl::ResourceTag colorOutTag = sl::ResourceTag{ &colorOut, sl::kBufferTypeScalingOutputColor, sl::ResourceLifecycle::eOnlyValidNow, &fullExtent };
444+
445+
sl::ResourceTag resourceTags[] = { colorInTag, colorOutTag };
446+
447+
slSetTag(viewport, resourceTags, _countof(resourceTags), globals::d3d::context);
448+
449+
sl::ViewportHandle view(viewport);
450+
const sl::BaseStructure* inputs[] = { &view };
451+
if (SL_FAILED(result, slEvaluateFeature(sl::kFeatureNIS, *frameToken, inputs, _countof(inputs), globals::d3d::context))) {
452+
logger::error("[Streamline] Failed to evaluate NIS feature");
453+
}
397454
}

src/Features/Upscaling/Streamline.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <sl_consts.h>
1515
#include <sl_dlss.h>
1616
#include <sl_matrix_helpers.h>
17+
#include <sl_nis.h>
1718
#include <sl_version.h>
1819
#pragma warning(pop)
1920

@@ -31,6 +32,7 @@ class Streamline
3132
bool triedInitialization = false;
3233

3334
bool featureDLSS = false;
35+
bool featureNIS = false;
3436

3537
sl::ViewportHandle viewport{ 0 };
3638

@@ -60,6 +62,10 @@ class Streamline
6062
PFun_slDLSSGetState* slDLSSGetState{};
6163
PFun_slDLSSSetOptions* slDLSSSetOptions{};
6264

65+
// NIS specific functions
66+
PFun_slNISSetOptions* slNISSetOptions{};
67+
PFun_slNISGetState* slNISGetState{};
68+
6369
Util::FrameChecker frameChecker;
6470
sl::FrameToken* frameToken = nullptr;
6571

@@ -79,4 +85,6 @@ class Streamline
7985
float GetInputResolutionScale(uint32_t outputWidth, uint32_t outputHeight, uint32_t qualityPreset);
8086

8187
void DestroyDLSSResources();
88+
89+
void ApplyNISSharpening(ID3D11Resource* a_texture, float sharpness);
8290
};

0 commit comments

Comments
 (0)