1414NLOHMANN_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
416425Upscaling::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
423432void 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+
13311381void 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}
0 commit comments