Graphics card profiles: Difference between revisions

m
Elgaton moved page Graphics Card Profiles to Graphics card profiles: Lowercase title as per FGW:MOS
m (Elgaton moved page Graphics Card Profiles to Graphics card profiles: Lowercase title as per FGW:MOS)
 
(25 intermediate revisions by one other user not shown)
Line 1: Line 1:
{{Stub}}
{{Stub}}
{{Non-stable|version=2016.4|progress=30}}
{{Portability Navbar}}
{{Portability Navbar}}
== Motivation ==
== Motivation ==
This particular idea dates back to early 2016 when a few FlightGear contributors were discussing a reddit review of FlightGear on the forum which highlighted that FlightGear's default graphics settings didn't seem to fit/match the graphics hardware available.
This particular idea dates back to early 2016 when a few FlightGear contributors were discussing a reddit review of FlightGear on the forum which highlighted that FlightGear's default graphics settings didn't seem to fit/match the graphics hardware available, i.e. rather plain default settings compared to the powerful graphics card available.


== Background ==
== Background ==


FlightGear core deveoper Erik Hofman came up with the idea to preselect more appropriate default settings based on parsing various GL_* strings (in particular GL_VENDOR), i.e. detect the video card and based on the GL renderer name turn on [[ALS]] (or not), turn on water shader (or not), turn on the 3d city shader (or not), etc.
FlightGear core deveoper Erik Hofman came up with the idea to preselect more appropriate default settings based on parsing various GL_* strings (in particular GL_VENDOR and GL_RENDERER), i.e. detect the video card and based on the GL renderer name turn on [[ALS]] (or not), turn on water shader (or not), turn on the 3d city shader (or not), etc.
 
At runtime, that data is already available in the form of properties that are copied to the property tree during initialization.


== Idea ==
== Idea ==
This approach is largely inspired by the way FlightGear already supports a variety of different joysticks and other I/O hardware using XML-configurable hardware profiles.
This approach is largely inspired by the way FlightGear already supports a variety of different joysticks and other I/O hardware using XML-configurable hardware profiles.


The defaults would not be touched but based on the detected video card certain options would get enabled, making the first impression much more pleasant (for first time users). <ref>{{cite web
The defaults [[Preferences.xml configuration file]] would not be touched but based on the detected video card certain options would get enabled, making the first impression much more pleasant (for first time users). <ref>{{cite web
   | url    = http://forum.flightgear.org/viewtopic.php?p=275302#p275302
   | url    = http://forum.flightgear.org/viewtopic.php?p=275302#p275302
   | title  = <nowiki>Re: Review of FG on reddit: xpost</nowiki>
   | title  = <nowiki>Re: Review of FG on reddit: xpost</nowiki>
Line 19: Line 22:
   | script_version = 0.25
   | script_version = 0.25
   }}</ref>
   }}</ref>
[[Autosave.xml configuration file]] would need to override any settings from such a standard gpu profile.


Furthermore, people agreed that it could be a good idea to make sure the configuration has at least 30fps at the default airport.
Furthermore, people agreed that it could be a good idea to make sure the configuration has at least 30fps at the default airport.
Line 43: Line 48:
   }}</ref>
   }}</ref>


We can do that by settings /sim/rendering/* as required, i.e. loading pre-configured profiles from $FG_ROOT
We can do that by setting /sim/rendering/* as required, i.e. loading pre-configured profiles from $FG_ROOT.
CPU/RAM and VRAM info is not currently available, but we have patches providing this sort of info <ref>{{cite web
For example, $FG_ROOT {{Fgdata file|gui/dialogs/about.xml}} and {{Fgdata file|gui/dialogs/rendering.xml}} are already accessing some of the GL* data via properties, e.g. to display the Intel warning, but also the GPU vendor info:
  | url    = http://forum.flightgear.org/viewtopic.php?p=275310#p275310
  | title  = <nowiki>Re: Review of FG on reddit: xpost</nowiki>
  | author = <nowiki>Hooray</nowiki>
  | date  = Feb 7th, 2016
  | added  = Feb 7th, 2016
  | script_version = 0.25
  }}
</ref> :
 
[[File:Sigar-support.png|250px|[[Resource Tracking for FlightGear]]]]


For example, $FG_ROOT/gui/dialogs/about.xml and rendering.xml are already accessing some of the GL* data via properties, e.g. to display the Intel warning, but also the GPU vendor info:
[[File:About dialog 2.10.png|thumb|right|[[About dialog]] ]]
 
[[File:About dialog 2.10.png|250px|[[About dialog]] ]]


Thus, we would ideally introduce 3-4 "vendor"-specific folders and then introduce a PropertyList XML file where the RENDERER string is used to select a certain default configuration.
Thus, we would ideally introduce 3-4 "vendor"-specific folders and then introduce a PropertyList XML file where the RENDERER string is used to select a certain default configuration.
Line 71: Line 64:
   }}
   }}
</ref>
</ref>
However, CPU/RAM and VRAM info is not currently available, but we have patches providing this sort of info <ref>{{cite web
  | url    = http://forum.flightgear.org/viewtopic.php?p=275310#p275310
  | title  = <nowiki>Re: Review of FG on reddit: xpost</nowiki>
  | author = <nowiki>Hooray</nowiki>
  | date  = Feb 7th, 2016
  | added  = Feb 7th, 2016
  | script_version = 0.25
  }}
</ref>
[[File:Sigar-support.png|thumb|right|[[Resource Tracking for FlightGear]]]]


<references/>
<references/>
== Heuristics ==
At runtime, we are already running some heuristics to make certain features available selectively, or to enable end-users to provide better troubleshooting information:
* {{Fgdata file|gui/dialogs/about.xml}}
* {{Fgdata file|gui/dialogs/rendering.xml}}
<syntaxhighlight lang="javascript">
      var vendor = getprop("/sim/rendering/gl-vendor");
      if (vendor != nil) {
        vendor = string.lc(vendor);
        if (find("intel", vendor) != -1) {
          setprop("/sim/gui/dialogs/rendering/shader-warning", 1);
        } else {
          setprop("/sim/gui/dialogs/rendering/shader-warning", 0);
        }
      }
</syntaxhighlight>


== Approach ==
== Approach ==
Line 123: Line 147:
<references/>
<references/>
== Status ==
== Status ==
{{Note|Erik committed a slightly different version of this [https://sourceforge.net/p/flightgear/flightgear/ci/e1bb47bc8938dd51a6159209665ce0575aac1bbc/]
{{FGCquote
|1= there is now an option in the Debug menu to 'Save Video Configuration' which creates a file with the correct name and the proper properties for inclusion in the Video section of FGData.
|2= {{cite web
  | url    = http://forum.flightgear.org/viewtopic.php?p=280074#p280074
  | title  = <nowiki>Re: Per video card configuration</nowiki>
  | author = <nowiki>erik</nowiki>
  | date  = Mar 21st, 2016
  | added  = Mar 21st, 2016
  | script_version = 0.25
  }}
}}
}}
As of 03/2016, there's a patch which will basically apply the logic for loading the [[Preferences.xml configuration file]] to load another [[PropertyList XML File]] into the <code>/sim/rendering</code> branch of the FlightGear [[Property tree]] after the initialization of the OSG/OpenGL graphics context (GC) has finished.
This would make it possible to either hard-code heuristics in C++ space to load vendor/renderer-based files from a certain XML node, or delegate doing that to scripting space.


== Issues ==
== Issues ==
When preferences.xml, autosave.xml etc are loaded, the gl-vendor properties are not yet initialized, because that requires an actual GC (OSG graphics context), so that loading the overlay may need to be delayed or the initialization sequence changed accordingly.
When preferences.xml, autosave.xml etc are loaded, the gl-vendor properties are not yet initialized, because that requires an actual GC (OSG graphics context), so that loading the XML overlay may need to be delayed or the initialization sequence changed accordingly.


We could also store a copy of the rendering specific state from autosave.xml and apply that within the GC::run() method, i.e. after loading graphics profiles there (straightforward).
We could also store a copy of the rendering specific state from autosave.xml and apply that within the GC::run() method, i.e. after loading graphics profiles there (straightforward).
Line 132: Line 173:




{{Flightgear file|GUI/gui.cxx|l=102}}
{{Flightgear file|src/GUI/gui.cxx|l=102}}
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
// Operation for querying OpenGL parameters. This must be done in a
// Operation for querying OpenGL parameters. This must be done in a
Line 178: Line 219:


== Roadmap ==
== Roadmap ==
== Organization of Profiles ==
== Implementation ==
== Implementation ==


Line 208: Line 252:


== Proof of Concept ==
== Proof of Concept ==
{{PD-author|FlightGear forum}}
<!--
{{WIP}}
{{WIP}}
-->
{{Note|This is just intended to demonstrate the concept; this moves the loading of the gpu profile  to the run() method of the GeneralInitOperation struct in GUI/gui.cxx, so that we can access the gl-vendor and gl-renderer information to proceed from here. To test this, use <code>--prop:/sim/startup/enable-gpu-profiles{{=}}1</code>
It would make more sense to restore a copy of any autosave.xml settings, i.e. those having the userarchive attribute set.
To actually do some kind of heuristics processing, it would make sense to support SGConditions, PropertyRules and/or Nasal (at least temporarily), so that we can process a few properties and select appropriate defaults.
}}
<syntaxhighlight lang="diff">diff --git a/src/GUI/gui.cxx b/src/GUI/gui.cxx
index b8a8f33..59f6dbf 100644
--- a/src/GUI/gui.cxx
+++ b/src/GUI/gui.cxx
@@ -109,8 +109,31 @@ struct GeneralInitOperation : public GraphicsContextOperation
        : GraphicsContextOperation(std::string("General init"))
    {
    }
+    ~GeneralInitOperation() {
+ SG_LOG(SG_GL, SG_INFO, "GeneralInitOperation finished");
+    }
+
+    void applyGraphicsProfile() {
+    try {
+      SGPropertyNode* rendering = fgGetNode("/sim/rendering");
+ std::string path = "Profiles/graphics.xml";
+ if(rendering) {
+ SG_LOG(SG_INPUT, SG_INFO, "Loading graphics profiles from:" <<path);
+ //TODO: in its current form, this will overwrite autosave stuff
+      fgLoadProps(path.c_str(), rendering);
+ }
+ else SG_LOG(SG_INPUT, SG_ALERT, "Could not acquire handle to /sim/rendering for loading graphics profile from "<<path);
+      }
+      catch (const std::exception& e) {
+                SG_LOG(SG_INPUT, SG_INFO, "caught std::exception trying to read graphics profile");
+            } catch (...) {
+                SG_LOG(SG_INPUT, SG_INFO, "caught generic exception trying to read graphics profile");
+            }
+    } // of applyGraphicsProfile
+
    void run(osg::GraphicsContext* gc)
    {
+ SG_LOG(SG_GL, SG_INFO, "OpenGL initialization");
        SGPropertyNode* simRendering = fgGetNode("/sim/rendering");
        simRendering->setStringValue("gl-vendor", (char*) glGetString(GL_VENDOR));
@@ -138,6 +161,12 @@ struct GeneralInitOperation : public GraphicsContextOperation
        glGetIntegerv( GL_DEPTH_BITS, &tmp );
        simRendering->setIntValue("depth-buffer-bits", tmp);
+ SG_LOG(SG_GL, SG_INFO, "OpenGL strings copied to property tree");
+
+ if(fgGetNode("/sim/startup")->getBoolValue("enable-gpu-profiles",true)) {
+ applyGraphicsProfile();
+ }
+ else SG_LOG(SG_GL, SG_INFO, "NOT applying standard gpu profiles!");
    }
};
</syntaxhighlight>


{{Note|$FG_ROOT/Profiles/graphics.xml (this is just a copy of the /rendering portion of preferences.xml for now)
{{Note|This is to be put into <code>$FG_ROOT/Profiles/graphics.xml</code> (for now, this is just a copy of the /sim/rendering portion of [[preferences.xml]] )
}}
}}
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
Line 469: Line 574:
</PropertyList>
</PropertyList>
<!-- end of graphics.xml -->
<!-- end of graphics.xml -->
</syntaxhighlight>
{{Note|
}}
<syntaxhighlight lang="diff">diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx
index b7fea20..615d0a9 100644
--- a/src/Main/fg_init.cxx
+++ b/src/Main/fg_init.cxx
@@ -469,7 +469,24 @@ int fgInitConfig ( int argc, char **argv, bool reinit )
      SG_LOG(SG_INPUT, SG_INFO, "Reading global preferences");
      fgLoadProps("preferences.xml", globals->get_props());
      SG_LOG(SG_INPUT, SG_INFO, "Finished Reading global preferences");
-       
+   
+      // Next, try to load defaults for /sim/rendering
+      SGPropertyNode* fgroot = globals->get_props();
+      try {
+      SGPropertyNode* rendering = fgroot->getNode("/sim/rendering");
+ std::string path = "Profiles/graphics.xml";
+ if(rendering) {
+ SG_LOG(SG_INPUT, SG_INFO, "Loading graphics profiles from:" <<path);
+      fgLoadProps(path.c_str(), rendering);
+ }
+ else SG_LOG(SG_INPUT, SG_ALERT, "Could not acquire handle to /sim/rendering for loading graphics profile from "<<path);
+      }
+      catch (const std::exception& e) {
+                SG_LOG(SG_INPUT, SG_INFO, "caught std::exception trying to read graphics profile");
+            } catch (...) {
+                SG_LOG(SG_INPUT, SG_INFO, "caught generic exception trying to read graphics profile");
+            }
+
      // do not load user settings when reset to default is requested, or if
      // told to explicitly ignore
      if (options->isOptionSet("restore-defaults") || options->isOptionSet("ignore-autosave"))


</syntaxhighlight>
</syntaxhighlight>
329

edits