Easier shader debugging
authorJani Uusi-Rantala <jani.uusi-rantala@nokia.com>
Sun, 9 Oct 2011 18:06:49 +0000 (21:06 +0300)
committerQt by Nokia <qt-info@nokia.com>
Mon, 10 Oct 2011 11:17:44 +0000 (13:17 +0200)
- Dumps out also the source code of the failed shader if available

Change-Id: I9ae80e6a6749446c5ff54db1bc324cc7411a81a7
Signed-off-by: Jani Uusi-Rantala <jani.uusi-rantala@nokia.com>
Reviewed-on: http://codereview.qt-project.org/6269
Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
src/gui/opengl/qopenglshaderprogram.cpp

index aa7767a..3c93b12 100644 (file)
@@ -213,17 +213,17 @@ bool QOpenGLShaderPrivate::compile(QOpenGLShader *q)
     GLuint shader = shaderGuard ? shaderGuard->id() : 0;
     if (!shader)
         return false;
+
+    // Try to compile shader
     glfuncs->glCompileShader(shader);
     GLint value = 0;
+
+    // Get compilation status
     glfuncs->glGetShaderiv(shader, GL_COMPILE_STATUS, &value);
     compiled = (value != 0);
-    value = 0;
-    glfuncs->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &value);
-    if (!compiled && value > 1) {
-        char *logbuf = new char [value];
-        GLint len;
-        glfuncs->glGetShaderInfoLog(shader, value, &len, logbuf);
-        log = QString::fromLatin1(logbuf);
+
+    if (!compiled) {
+        // Compilation failed, try to provide some information about the failure
         QString name = q->objectName();
 
         const char *types[] = {
@@ -241,13 +241,53 @@ bool QOpenGLShaderPrivate::compile(QOpenGLShader *q)
         else if (shaderType == QOpenGLShader::Geometry)
             type = types[2];
 
+        // Get info and source code lengths
+        GLint infoLogLength = 0;
+        GLint sourceCodeLength = 0;
+        char *logBuffer = 0;
+        char *sourceCodeBuffer = 0;
+
+        // Get the compilation info log
+        glfuncs->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+        if (infoLogLength > 1) {
+            GLint temp;
+            logBuffer = new char [infoLogLength];
+            glfuncs->glGetShaderInfoLog(shader, infoLogLength, &temp, logBuffer);
+        }
+
+        // Get the source code
+        glfuncs->glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceCodeLength);
+
+        if (sourceCodeLength > 1) {
+            GLint temp;
+            sourceCodeBuffer = new char [sourceCodeLength];
+            glfuncs->glGetShaderSource(shader, sourceCodeLength, &temp, sourceCodeBuffer);
+        }
+
+        QString log;
+        if (logBuffer)
+            log = QString::fromLatin1(logBuffer);
+        else
+            log = QLatin1String("failed");
+
         if (name.isEmpty())
             qWarning("QOpenGLShader::compile(%s): %s", type, qPrintable(log));
         else
             qWarning("QOpenGLShader::compile(%s)[%s]: %s", type, qPrintable(name), qPrintable(log));
 
-        delete [] logbuf;
+        // Dump the source code if we got it
+        if (sourceCodeBuffer) {
+            qWarning("*** Problematic %s shader source code ***", type);
+            qWarning() << qPrintable(QString::fromLatin1(sourceCodeBuffer));
+            qWarning("***");
+        }
+
+        // Cleanup
+        delete [] logBuffer;
+        delete [] sourceCodeBuffer;
     }
+
     return compiled;
 }