0030166: Visualization, TKOpenGl - add option OpenGl_Caps::glslDumpLevel dumping...
authormnv <mnv@opencascade.com>
Thu, 27 Sep 2018 13:30:48 +0000 (16:30 +0300)
committerapn <apn@opencascade.com>
Wed, 10 Oct 2018 15:48:37 +0000 (18:48 +0300)
Added new option -glslcode for vgldebug command with the following values:
- off   disables glsl source code dump;
- short to dump glsl source code in short format (except common declarations);
- full  to dump glsl source code in full format.

src/OpenGl/FILES
src/OpenGl/OpenGl_Caps.cxx
src/OpenGl/OpenGl_Caps.hxx
src/OpenGl/OpenGl_ShaderProgram.cxx
src/OpenGl/OpenGl_ShaderProgramDumpLevel.hxx [new file with mode: 0644]
src/ViewerTest/ViewerTest_ViewerCommands.cxx

index 25b92ca..52c9165 100755 (executable)
@@ -141,3 +141,4 @@ OpenGl_VertexBufferEditor.hxx
 OpenGl_TextBuilder.hxx
 OpenGl_TextBuilder.cxx
 OpenGl_HaltonSampler.hxx
+OpenGl_ShaderProgramDumpLevel.hxx
index fc48e43..dc03616 100755 (executable)
@@ -52,7 +52,8 @@ OpenGl_Caps::OpenGl_Caps()
   contextCompatible (Standard_False),
 #endif
   glslWarnings      (Standard_False),
-  suppressExtraMsg  (Standard_True)
+  suppressExtraMsg  (Standard_True),
+  glslDumpLevel     (OpenGl_ShaderProgramDumpLevel_Off)
 {
   //
 }
@@ -77,6 +78,7 @@ OpenGl_Caps& OpenGl_Caps::operator= (const OpenGl_Caps& theCopy)
   contextCompatible = theCopy.contextCompatible;
   glslWarnings      = theCopy.glslWarnings;
   suppressExtraMsg  = theCopy.suppressExtraMsg;
+  glslDumpLevel     = theCopy.glslDumpLevel;
   return *this;
 }
 
index 6e00339..c94633a 100755 (executable)
@@ -18,6 +18,7 @@
 
 #include <Standard_Type.hxx>
 #include <Standard_Transient.hxx>
+#include <OpenGl_ShaderProgramDumpLevel.hxx>
 
 //! Class to define graphic driver capabilities.
 //! Notice that these options will be ignored if particular functionality does not provided by GL driver
@@ -113,6 +114,9 @@ public: //! @name flags to activate verbose output
   //! Suppress redundant messages from debug GL context. ON by default.
   Standard_Boolean suppressExtraMsg;
 
+  //! Print GLSL program source code. OFF by default.
+  OpenGl_ShaderProgramDumpLevel glslDumpLevel;
+
 public: //! @name class methods
 
   //! Default constructor - initialize with most optimal values.
index 3b2bb56..0d665d0 100755 (executable)
@@ -165,6 +165,24 @@ OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram
   }
 }
 
+//! Puts line numbers to the output of GLSL program source code.
+static TCollection_AsciiString putLineNumbers (const TCollection_AsciiString& theSource)
+{
+  std::stringstream aStream;
+  theSource.Print (aStream);
+  std::string aLine;
+  Standard_Integer aLineNumber = 1;
+  TCollection_AsciiString aResultSource;
+  while (std::getline (aStream, aLine))
+  {
+    TCollection_AsciiString anAsciiString = TCollection_AsciiString (aLine.c_str());
+    anAsciiString.Prepend (TCollection_AsciiString ("\n") + TCollection_AsciiString (aLineNumber) + ": ");
+    aResultSource += anAsciiString;
+    aLineNumber++;
+  }
+  return aResultSource;
+}
+
 // =======================================================================
 // function : Initialize
 // purpose  : Initializes program object with the list of shader objects
@@ -381,7 +399,7 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
 
     if (!aShader->Compile (theCtx))
     {
-      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource);
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, putLineNumbers (aSource));
       TCollection_AsciiString aLog;
       aShader->FetchInfoLog (theCtx, aLog);
       if (aLog.IsEmpty())
@@ -405,6 +423,33 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
       }
     }
 
+    if (theCtx->caps->glslDumpLevel)
+    {
+      TCollection_AsciiString aShaderTypeMsg;
+      switch (anIter.Value()->Type())
+      {
+        case Graphic3d_TOS_COMPUTE:         { aShaderTypeMsg = "Compute shader source code:\n";                break; }
+        case Graphic3d_TOS_VERTEX:          { aShaderTypeMsg = "Vertex shader source code:\n";                 break; }
+        case Graphic3d_TOS_TESS_CONTROL:    { aShaderTypeMsg = "Tesselation control shader source code:\n";    break; }
+        case Graphic3d_TOS_TESS_EVALUATION: { aShaderTypeMsg = "Tesselation evaluation shader source code:\n"; break; }
+        case Graphic3d_TOS_GEOMETRY:        { aShaderTypeMsg = "Geometry shader source code:\n";               break; }
+        case Graphic3d_TOS_FRAGMENT:        { aShaderTypeMsg = "Fragment shader source code:\n";               break; }
+      }
+      TCollection_AsciiString anOutputSource = aSource;
+      if (theCtx->caps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short)
+      {
+        anOutputSource = aHeaderVer
+                       + (!aHeaderVer.IsEmpty() ? "\n" : "")
+                       + anExtensions
+                       + aPrecisionHeader
+                       + aHeaderType
+                       + aHeaderConstants
+                       + anIter.Value()->Source();
+      }
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_MEDIUM,
+                           TCollection_ExtendedString (aShaderTypeMsg + anOutputSource));
+    }
+
     if (!AttachShader (theCtx, aShader))
     {
       aShader->Release (theCtx.operator->());
diff --git a/src/OpenGl/OpenGl_ShaderProgramDumpLevel.hxx b/src/OpenGl/OpenGl_ShaderProgramDumpLevel.hxx
new file mode 100644 (file)
index 0000000..5d8730b
--- /dev/null
@@ -0,0 +1,27 @@
+// Created on: 2018-10-04
+// Created by: Maxim NEVROV
+// Copyright (c) 2018 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _OpenGl_ShaderProgramDumpLevel_H__
+#define _OpenGl_ShaderProgramDumpLevel_H__
+
+//! Definition of shader programs source code dump levels.
+enum OpenGl_ShaderProgramDumpLevel
+{
+  OpenGl_ShaderProgramDumpLevel_Off,  //!< Disable shader programs source code dump.
+  OpenGl_ShaderProgramDumpLevel_Short, //!< Shader programs source code dump in short format (except common declarations).
+  OpenGl_ShaderProgramDumpLevel_Full //!< Shader programs source code dump in full format.
+};
+
+#endif // _OpenGl_ShaderProgramDumpLevel_H__
\ No newline at end of file
index f063bbf..73b88b8 100644 (file)
@@ -5604,6 +5604,33 @@ static int VFps (Draw_Interpretor& theDI,
   return 0;
 }
 
+//! Auxiliary function for parsing glsl dump level argument.
+static Standard_Boolean parseGlslSourceFlag (Standard_CString               theArg,
+                                             OpenGl_ShaderProgramDumpLevel& theGlslDumpLevel)
+{
+  TCollection_AsciiString aTypeStr (theArg);
+  aTypeStr.LowerCase();
+  if (aTypeStr == "off"
+   || aTypeStr == "0")
+  {
+    theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
+  }
+  else if (aTypeStr == "short")
+  {
+    theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Short;
+  }
+  else if (aTypeStr == "full"
+        || aTypeStr == "1")
+  {
+    theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Full;
+  }
+  else
+  {
+    return Standard_False;
+  }
+  return Standard_True;
+}
+
 //==============================================================================
 //function : VGlDebug
 //purpose  :
@@ -5641,10 +5668,19 @@ static int VGlDebug (Draw_Interpretor& theDI,
       }
     }
 
-    theDI << "debug:   " << (aCaps->contextDebug      ? "1" : "0") << aDebActive  << "\n"
-          << "sync:    " << (aCaps->contextSyncDebug  ? "1" : "0") << aSyncActive << "\n"
-          << "glslWarn:" << (aCaps->glslWarnings      ? "1" : "0") << "\n"
-          << "extraMsg:" << (aCaps->suppressExtraMsg  ? "0" : "1") << "\n";
+    TCollection_AsciiString aGlslCodeDebugStatus = TCollection_AsciiString()
+      + "glslSourceCode: "
+      + (aCaps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Off
+         ? "Off"
+         : aCaps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short
+          ? "Short"
+          : "Full")
+      + "\n";
+    theDI << "debug:          " << (aCaps->contextDebug      ? "1" : "0") << aDebActive  << "\n"
+          << "sync:           " << (aCaps->contextSyncDebug  ? "1" : "0") << aSyncActive << "\n"
+          << "glslWarn:       " << (aCaps->glslWarnings      ? "1" : "0") << "\n"
+          << aGlslCodeDebugStatus
+          << "extraMsg:       " << (aCaps->suppressExtraMsg  ? "0" : "1") << "\n";
     return 0;
   }
 
@@ -5717,6 +5753,21 @@ static int VGlDebug (Draw_Interpretor& theDI,
         aDefCaps->contextDebug = Standard_True;
       }
     }
+    else if (anArgCase == "-glslsourcecode"
+          || anArgCase == "-glslcode")
+    {
+      OpenGl_ShaderProgramDumpLevel aGslsDumpLevel = OpenGl_ShaderProgramDumpLevel_Full;
+      if (++anArgIter < theArgNb
+      && !parseGlslSourceFlag (theArgVec[anArgIter], aGslsDumpLevel))
+      {
+        --anArgIter;
+      }
+      aDefCaps->glslDumpLevel = aGslsDumpLevel;
+      if (aCaps != NULL)
+      {
+        aCaps->glslDumpLevel = aGslsDumpLevel;
+      }
+    }
     else if (anArgCase == "-debug")
     {
       if (++anArgIter < theArgNb
@@ -5733,6 +5784,18 @@ static int VGlDebug (Draw_Interpretor& theDI,
       aDefCaps->contextDebug     = toEnableDebug;
       aDefCaps->contextSyncDebug = toEnableDebug;
       aDefCaps->glslWarnings     = toEnableDebug;
+      aDefCaps->glslDumpLevel    = toEnableDebug ? OpenGl_ShaderProgramDumpLevel_Full
+                                                 : OpenGl_ShaderProgramDumpLevel_Off;
+      aDefCaps->suppressExtraMsg = !toEnableDebug;
+      if (aCaps != NULL)
+      {
+        aCaps->contextDebug     = toEnableDebug;
+        aCaps->contextSyncDebug = toEnableDebug;
+        aCaps->glslWarnings     = toEnableDebug;
+        aCaps->glslDumpLevel    = toEnableDebug ? OpenGl_ShaderProgramDumpLevel_Full
+                                                : OpenGl_ShaderProgramDumpLevel_Off;
+        aCaps->suppressExtraMsg = !toEnableDebug;
+      }
     }
     else
     {
@@ -12117,13 +12180,15 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     __FILE__, VFps, group);
   theCommands.Add ("vgldebug",
             "vgldebug [-sync {0|1}] [-debug {0|1}] [-glslWarn {0|1}]"
-    "\n\t\t:          [-extraMsg {0|1}] [{0|1}]"
+    "\n\t\t:          [-glslCode {off|short|full}] [-extraMsg {0|1}] [{0|1}]"
     "\n\t\t: Request debug GL context. Should be called BEFORE vinit."
     "\n\t\t: Debug context can be requested only on Windows"
     "\n\t\t: with GL_ARB_debug_output extension implemented by GL driver!"
     "\n\t\t:  -sync     - request synchronized debug GL context"
     "\n\t\t:  -glslWarn - log GLSL compiler/linker warnings,"
     "\n\t\t:              which are suppressed by default,"
+    "\n\t\t:  -glslCode - log GLSL program source code,"
+    "\n\t\t:              which are suppressed by default,"
     "\n\t\t:  -extraMsg - log extra diagnostic messages from GL context,"
     "\n\t\t:              which are suppressed by default",
     __FILE__, VGlDebug, group);