17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-01 05:42:44 +01:00

Add NVIDIA DLSS to the Vulkan renderer (gfx.antialiasing dlss/dlaa) and gfx.buffer.percent

This commit is contained in:
2026-10-25 19:35:33 +01:00
parent 71a6628a4a
commit 1841e6d7b0
27 changed files with 1487 additions and 56 deletions

View File

@@ -77,6 +77,12 @@ void global_settings::FinalizeConfig()
#endif
}
glm::ivec2 global_settings::gfx_buffer_size(float const Scale) const
{
auto const scale{Scale > 0.f ? Scale : gfx_buffer_scale};
return glm::max(glm::ivec2(glm::round(glm::vec2(fb_size) * scale)), glm::ivec2(1));
}
bool global_settings::ConfigParseGeneral(cParser& Parser, const std::string& token)
{
if (token == "sceneryfile")
@@ -1463,15 +1469,24 @@ global_settings::ConfigParse_gfx( cParser &Parser, std::string_view const Token
Parser.getTokens(1, false);
Parser >> reflectiontune.range_vehicles;
}
else if (Token == "gfx.framebuffer.width")
else if ((Token == "gfx.framebuffer.width") || (Token == "gfx.framebuffer.height"))
{
// the size of the image is a part of the size of the window now (gfx.buffer.percent)
Parser.getTokens(1, false);
Parser >> gfx_framebuffer_width;
int ignored{0};
Parser >> ignored;
WriteLog("eu07.ini: \"" + std::string(Token) + "\" is no longer supported and was ignored, use gfx.buffer.percent");
}
else if (Token == "gfx.framebuffer.height")
else if (Token == "gfx.buffer.percent")
{
// a part of the window: 0.5 is half its width and half its height. a value over 4 is taken as percents (50: 0.5)
Parser.getTokens(1, false);
Parser >> gfx_framebuffer_height;
Parser >> gfx_buffer_scale;
if (gfx_buffer_scale > 4.f)
{
gfx_buffer_scale *= 0.01f;
}
gfx_buffer_scale = std::clamp(gfx_buffer_scale, 0.25f, 2.f);
}
else if (Token == "gfx.shadowmap.enabled")
{
@@ -1914,14 +1929,19 @@ global_settings::ConfigParse_gfx_sky( cParser &Parser, std::string_view const To
Parser >> level;
gfx_fog_quality = ( level == "low" || level == "1" ) ? 1 : ( level == "high" || level == "3" ) ? 3 : ( level == "ultra" || level == "4" ) ? 4 : 2; }
else if( Token == "gfx.antialiasing" ) {
// off, msaax2, msaax4, msaax8 or taa; it sets the multisampling too, the key which used to say it
// off, msaax2, msaax4, msaax8, taa, dlss or dlaa; it sets the multisampling too, the key which used to say it
Parser.getTokens( 1 );
std::string mode;
Parser >> mode;
std::transform( mode.begin(), mode.end(), mode.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower( c ) ); } );
gfx_dlss_native = false;
if( mode == "taa" ) {
gfx_antialiasing = antialiasing_mode::taa;
iMultisampling = 0; }
else if( mode == "dlss" || mode == "dlaa" ) {
gfx_antialiasing = antialiasing_mode::dlss;
gfx_dlss_native = ( mode == "dlaa" );
iMultisampling = 0; }
else if( mode == "msaax2" || mode == "msaax4" || mode == "msaax8" || mode == "msaax16" ) {
gfx_antialiasing = antialiasing_mode::msaa;
iMultisampling = ( mode == "msaax2" ) ? 1 : ( mode == "msaax4" ) ? 2 : ( mode == "msaax8" ) ? 3 : 4; }
@@ -1929,7 +1949,19 @@ global_settings::ConfigParse_gfx_sky( cParser &Parser, std::string_view const To
gfx_antialiasing = antialiasing_mode::off;
iMultisampling = 0; }
else {
ErrorLog( "Bad config: unknown gfx.antialiasing \"" + mode + "\", expected off, msaax2, msaax4, msaax8 or taa" ); } }
ErrorLog( "Bad config: unknown gfx.antialiasing \"" + mode + "\", expected off, msaax2, msaax4, msaax8, taa, dlss or dlaa" ); } }
else if( Token == "gfx.dlss.preset" ) {
// the presets of the dlss sdk 310 (the others are gone, deprecated or reserved)
Parser.getTokens( 1 );
std::string preset;
Parser >> preset;
std::transform( preset.begin(), preset.end(), preset.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower( c ) ); } );
gfx_dlss_preset = ( preset == "j" ) ? 10 : ( preset == "k" ) ? 11 : ( preset == "l" ) ? 12 : ( preset == "m" ) ? 13 : 0;
if( ( gfx_dlss_preset == 0 ) && ( preset != "default" ) ) {
ErrorLog( "Bad config: unknown gfx.dlss.preset \"" + preset + "\", expected default, j, k, l or m" ); } }
else if( Token == "gfx.dlss.autoexposure" ) { readswitch( gfx_dlss_autoexposure ); }
else if( Token == "gfx.dlss.lodbias" ) { readvalue( gfx_dlss_lodbias, -2.f, 2.f ); }
else if( Token == "gfx.dlss.developer" ) { readswitch( gfx_dlss_developer ); }
else if( Token == "gfx.fog.range" ) { readvalue( gfx_fog_range, 100.f, 10000.f ); }
else if( Token == "gfx.fog.lights" ) { readvalue( gfx_fog_lights, 0.f, 10.f ); }
else if( Token == "gfx.fog.shadows" ) { readswitch( gfx_fog_shadows ); }
@@ -2065,7 +2097,12 @@ global_settings::export_as_text( std::ostream &Output ) const {
export_as_text( Output, "gfx.reflections.fidelity", reflectiontune.fidelity );
export_as_text( Output, "timespeed", fTimeSpeed );
export_as_text( Output, "multisampling", iMultisampling );
export_as_text( Output, "gfx.antialiasing", std::string{ gfx_antialiasing == antialiasing_mode::taa ? "taa" : ( gfx_antialiasing == antialiasing_mode::off || iMultisampling == 0 ) ? "off" : "msaax" + std::to_string( 1 << iMultisampling ) } );
export_as_text( Output, "gfx.antialiasing", std::string{ gfx_antialiasing == antialiasing_mode::taa ? "taa" : gfx_antialiasing == antialiasing_mode::dlss ? ( gfx_dlss_native ? "dlaa" : "dlss" ) : ( gfx_antialiasing == antialiasing_mode::off || iMultisampling == 0 ) ? "off" : "msaax" + std::to_string( 1 << iMultisampling ) } );
export_as_text( Output, "gfx.buffer.percent", gfx_buffer_scale );
export_as_text( Output, "gfx.dlss.preset", std::string{ gfx_dlss_preset == 10 ? "j" : gfx_dlss_preset == 11 ? "k" : gfx_dlss_preset == 12 ? "l" : gfx_dlss_preset == 13 ? "m" : "default" } );
export_as_text( Output, "gfx.dlss.autoexposure", gfx_dlss_autoexposure );
export_as_text( Output, "gfx.dlss.lodbias", gfx_dlss_lodbias );
export_as_text( Output, "gfx.dlss.developer", gfx_dlss_developer );
export_as_text( Output, "latitude", fLatitudeDeg );
export_as_text( Output, "convertmodels", iConvertModels );
export_as_text( Output, "file.binary.terrain", file_binary_terrain );
@@ -2188,8 +2225,6 @@ global_settings::export_as_text( std::ostream &Output ) const {
<< extcam_res.y << "\n";
export_as_text( Output, "compresstex", compress_tex );
export_as_text( Output, "gfx.framebuffer.width", gfx_framebuffer_width );
export_as_text( Output, "gfx.framebuffer.height", gfx_framebuffer_height );
export_as_text( Output, "gfx.shadowmap.enabled", gfx_shadowmap_enabled );
// TODO: export fpslimit
export_as_text( Output, "randomseed", Global.random_seed );

View File

@@ -182,12 +182,30 @@ struct global_settings {
GLint iMaxTextureSize{ 4096 }; // maksymalny rozmiar tekstury
GLint iMaxCabTextureSize{ 4096 }; // largest allowed texture in vehicle cab
int iMultisampling{ 2 }; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px
// gfx.antialiasing: off, msaax2/x4/x8 (the samples go to iMultisampling) or taa (one sample, with the history of the last frames;
// iMultisampling 0). the old key multisampling sets msaa or off. read at the start
enum class antialiasing_mode { off, msaa, taa };
// gfx.antialiasing: off, msaax2/x4/x8 (the samples go to iMultisampling), taa (one sample, with the history of the last frames;
// iMultisampling 0) or dlss (nvidia dlss of the vulkan renderer, one sample: the image of gfx.buffer.percent upscaled to the
// window; dlaa is dlss at the full size of the window). the old key multisampling sets msaa or off. read at the start; where dlss
// can't be had at the start (the opengl renderers, no nvidia rtx, a build without WITH_DLSS) the renderer takes taa instead, a
// failure of dlss later leaves the scene stretched to the window without anti-aliasing
enum class antialiasing_mode { off, msaa, taa, dlss };
antialiasing_mode gfx_antialiasing{ antialiasing_mode::msaa };
// the temporal anti-aliasing is on: asked for, and the post-processing which does it is there
bool gfx_taa() const { return ( gfx_antialiasing == antialiasing_mode::taa ) && ( false == gfx_skippipeline ); }
// dlss is on: asked for, with the post-processing (the renderer sets gfx_antialiasing to taa where it can't have it)
bool gfx_dlss() const { return ( gfx_antialiasing == antialiasing_mode::dlss ) && ( false == gfx_skippipeline ); }
// gfx.buffer.percent: the size of the image the scene of the main window is drawn to, as a part of the size of the window
// (0.5: half its width and half its height). dlss upscales it to the window, the other modes stretch it. read at the start
float gfx_buffer_scale{ 1.f };
// gfx.antialiasing dlaa: dlss at the full size of the window whatever gfx.buffer.percent says
bool gfx_dlss_native{ false };
// gfx.dlss.preset: default, j, k, l or m, the value of NVSDK_NGX_DLSS_Hint_Render_Preset (0, 10, 11, 12, 13)
int gfx_dlss_preset{ 0 };
// gfx.dlss.autoexposure: dlss works the exposure out itself instead of taking the one of the tonemapping
bool gfx_dlss_autoexposure{ false };
// gfx.dlss.lodbias: added to the bias of the mipmaps of the textures of the scene dlss is given (log2(render / window) - 1)
float gfx_dlss_lodbias{ 0.f };
// gfx.dlss.developer: the development library of dlss (ngx_dev/ next to the program) with its indicator and debug keys
bool gfx_dlss_developer{ false };
float SplineFidelity{ 1.f }; // determines segment size during conversion of splines to geometry
float SleeperDistance{ 250.f }; // max distance (in meters) at which per-track sleeper models are still drawn; 0 disables sleeper rendering entirely
std::string Sleepers3D; // model of the sleepers and switch timbers laid where the simulator makes the ballast; empty: none
@@ -298,8 +316,13 @@ struct global_settings {
std::chrono::duration<float> python_minframetime {0.01f};
bool gfx_skiprendering = false;
// the size of the image the scene of the main window is drawn to: -1 until the renderer works it out from the window and
// gfx.buffer.percent (the old keys gfx.framebuffer.width and .height aren't taken any more)
int gfx_framebuffer_width = -1;
int gfx_framebuffer_height = -1;
// the size of the image of the main window drawn from the window and gfx.buffer.percent (Scale: the part of the window, 0: that
// of the settings), at least a pixel
glm::ivec2 gfx_buffer_size( float Scale = 0.f ) const;
bool gfx_shadowmap_enabled = true;
bool gfx_envmap_enabled = true;
bool gfx_lights_clustered = true; // headlights from the light lists of the clusters (no limit of lit headlights) or the first dynamiclights of them
@@ -367,8 +390,8 @@ struct global_settings {
// one for each of the last frames, instead of with glBufferSubData. read at the start
bool gfx_bufferstreaming = true;
bool gfx_postfx_motionblur_enabled = true;
// the colour pass writes the velocities of the pixels: for the motion blur, or for the temporal anti-aliasing
bool gfx_motion_vectors() const { return gfx_postfx_motionblur_enabled || gfx_taa(); }
// the colour pass writes the velocities of the pixels: for the motion blur, the temporal anti-aliasing or dlss
bool gfx_motion_vectors() const { return gfx_postfx_motionblur_enabled || gfx_taa() || gfx_dlss(); }
float gfx_postfx_motionblur_shutter = 0.01f;
GLenum gfx_postfx_motionblur_format = GL_RG16F;
GLenum gfx_format_color = GL_RGB16F;