]> git.cworth.org Git - apitrace/blobdiff - glstate.py
Understand D3DFMT_RAWZ too.
[apitrace] / glstate.py
index 9f683933223a1682392eb232af9540cfcf05ea8c..b54634e64efcd84985fae582cf0b4f2d27a638cb 100644 (file)
@@ -1754,7 +1754,7 @@ parameters = [
     ("glGet",  E,      1,      "GL_STENCIL_BACK_FAIL"),        # 0x8801
     ("glGet",  E,      1,      "GL_STENCIL_BACK_PASS_DEPTH_FAIL"),     # 0x8802
     ("glGet",  E,      1,      "GL_STENCIL_BACK_PASS_DEPTH_PASS"),     # 0x8803
-    ("glGet",  X,      1,      "GL_FRAGMENT_PROGRAM_ARB"),     # 0x8804
+    ("glGet",  B,      1,      "GL_FRAGMENT_PROGRAM_ARB"),     # 0x8804
     ("glGet",  X,      1,      "GL_PROGRAM_ALU_INSTRUCTIONS_ARB"),     # 0x8805
     ("glGet",  X,      1,      "GL_PROGRAM_TEX_INSTRUCTIONS_ARB"),     # 0x8806
     ("glGet",  X,      1,      "GL_PROGRAM_TEX_INDIRECTIONS_ARB"),     # 0x8807
@@ -2866,19 +2866,6 @@ class GetInflector:
         return self.suffixes[type]
 
 
-glGet = GetInflector('glGet', {
-    B: 'Booleanv',
-    I: 'Integerv',
-    F: 'Floatv',
-    D: 'Doublev',
-    S: 'String',
-    P: 'Pointerv',
-})
-
-glGetTexParameter = GetInflector('glGetTexParameter', {I: 'iv', F: 'fv'})
-
-
-
 class StateGetter(Visitor):
     '''Type visitor that is able to extract the state via one of the glGet*
     functions.
@@ -2886,46 +2873,61 @@ class StateGetter(Visitor):
     It will declare any temporary variable
     '''
 
-    def __init__(self, inflector):
-        self.inflector = inflector
+    def __init__(self, radical, suffixes):
+        self.inflector = GetInflector(radical, suffixes)
 
-    def temp_name(self, pname):
+    def __call__(self, *args):
+        pname = args[-1]
+
+        for function, type, count, name in parameters:
+            if type is X:
+                continue
+            if name == pname:
+                if count != 1:
+                    type = Array(type, str(count))
+
+                return type, self.visit(type, args)
+
+        raise NotImplementedError
+
+    def temp_name(self, args):
         '''Return the name of a temporary variable to hold the state.'''
+        pname = args[-1]
 
         return pname[3:].lower()
 
-    def visit_const(self, const, pname):
-        return self.visit(const.type, pname)
+    def visit_const(self, const, args):
+        return self.visit(const.type, args)
 
-    def visit_scalar(self, type, pname):
-        temp_name = self.temp_name(pname)
+    def visit_scalar(self, type, args):
+        temp_name = self.temp_name(args)
         elem_type = self.inflector.reduced_type(type)
         inflection = self.inflector.inflect(type)
         if inflection.endswith('v'):
             print '    %s %s = 0;' % (elem_type, temp_name)
-            print '    %s(%s, &%s);' % (inflection, pname, temp_name)
+            print '    %s(%s, &%s);' % (inflection, ', '.join(args), temp_name)
         else:
-            print '    %s %s = %s(%s);' % (elem_type, temp_name, inflection, pname)
+            print '    %s %s = %s(%s);' % (elem_type, temp_name, inflection, ', '.join(args))
         return temp_name
 
-    def visit_string(self, string, pname):
-        temp_name = self.temp_name(pname)
+    def visit_string(self, string, args):
+        temp_name = self.temp_name(args)
         inflection = self.inflector.inflect(string)
         assert not inflection.endswith('v')
-        print '    %s %s = (%s)%s(%s);' % (string, temp_name, string, inflection, pname)
+        print '    %s %s = (%s)%s(%s);' % (string, temp_name, string, inflection, ', '.join(args))
         return temp_name
 
-    def visit_alias(self, alias, pname):
-        return self.visit_scalar(alias, pname)
+    def visit_alias(self, alias, args):
+        return self.visit_scalar(alias, args)
 
-    def visit_enum(self, enum, pname):
-        return self.visit(GLint, pname)
+    def visit_enum(self, enum, args):
+        return self.visit(GLint, args)
 
-    def visit_bitmask(self, bitmask, pname):
-        return self.visit(GLint, pname)
+    def visit_bitmask(self, bitmask, args):
+        return self.visit(GLint, args)
 
-    def visit_array(self, array, pname):
-        temp_name = self.temp_name(pname)
+    def visit_array(self, array, args):
+        temp_name = self.temp_name(args)
         if array.length == '1':
             return self.visit(array.type)
         elem_type = self.inflector.reduced_type(array.type)
@@ -2933,18 +2935,31 @@ class StateGetter(Visitor):
         assert inflection.endswith('v')
         print '    %s %s[%s];' % (elem_type, temp_name, array.length)
         print '    memset(%s, 0, %s * sizeof *%s);' % (temp_name, array.length, temp_name)
-        print '    %s(%s, %s);' % (inflection, pname, temp_name)
+        print '    %s(%s, %s);' % (inflection, ', '.join(args), temp_name)
         return temp_name
 
-    def visit_opaque(self, pointer, pname):
-        temp_name = self.temp_name(pname)
+    def visit_opaque(self, pointer, args):
+        temp_name = self.temp_name(args)
         inflection = self.inflector.inflect(pointer)
         assert inflection.endswith('v')
         print '    GLvoid *%s;' % temp_name
-        print '    %s(%s, &%s);' % (inflection, pname, temp_name)
+        print '    %s(%s, &%s);' % (inflection, ', '.join(args), temp_name)
         return temp_name
 
 
+glGet = StateGetter('glGet', {
+    B: 'Booleanv',
+    I: 'Integerv',
+    F: 'Floatv',
+    D: 'Doublev',
+    S: 'String',
+    P: 'Pointerv',
+})
+
+glGetVertexAttrib = StateGetter('glGetVertexAttrib', {I: 'iv', F: 'fv', D: 'dv', P: 'Pointerv'})
+glGetTexParameter = StateGetter('glGetTexParameter', {I: 'iv', F: 'fv'})
+
+
 class JsonWriter(Visitor):
     '''Type visitor that will dump a value of the specified type through the
     JSON writer.
@@ -3009,77 +3024,128 @@ class StateDumper:
         print '#include "glretrace.hpp"'
         print
 
-        print 'static void'
-        print 'writeEnum(JSONWriter &json, GLenum pname)'
+        print 'static const char *'
+        print '_enum_string(GLenum pname)'
         print '{'
         print '    switch(pname) {'
         for name in GLenum.values:
             print '    case %s:' % name
-            print '        json.writeString("%s");' % name
-            print '        break;'
+            print '        return "%s";' % name
         print '    default:'
-        print '        json.writeNumber(pname);'
+        print '        return NULL;'
         print '    }'
         print '}'
         print
 
-        # shaders
-        print 'static void'
-        print 'writeShader(JSONWriter &json, GLuint shader)'
+        print 'static const char *'
+        print 'enum_string(GLenum pname)'
         print '{'
-        print '    if (!shader) {'
-        print '        json.writeNull();'
-        print '        return;'
-        print '    }'
-        print
-        print '    json.beginObject();'
-        print '    GLint source_length = 0;'
-        print '    glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &source_length);'
-        print '    json.beginMember("source");'
-        print '    if (source_length) {'
-        print '        GLchar *source = new GLchar[source_length];'
-        print '        GLsizei length = 0;'
-        print '        source[0] = 0;'
-        print '        glGetShaderSource(shader, source_length, &length, source);'
-        print '        json.writeString(source);'
-        print '        delete [] source;'
+        print '    const char *s = _enum_string(pname);'
+        print '    if (s) {'
+        print '        return s;'
         print '    } else {'
-        print '        json.writeNull();'
+        print '        static char buf[16];'
+        print '        snprintf(buf, sizeof buf, "0x%04x", pname);'
+        print '        return buf;'
         print '    }'
-        print '    json.endMember(); // source'
-        print '    json.endObject();'
         print '}'
         print
 
-        # programs
         print 'static inline void'
-        print 'writeProgram(JSONWriter &json, GLuint program)'
+        print 'writeEnum(JSONWriter &json, GLenum pname)'
         print '{'
-        print '    if (!program) {'
-        print '        json.writeNull();'
-        print '        return;'
-        print '    }'
-        print
-        print '    json.beginObject();'
-        print '    json.beginMember("attached_shaders");'
-        print '    GLint attached_shaders = 0;'
-        print '    glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);'
-        print '    json.beginArray();'
-        print '    if (attached_shaders) {'
-        print '        GLuint *shaders = new GLuint[attached_shaders];'
-        print '        GLsizei count = 0;'
-        print '        glGetAttachedShaders(program, attached_shaders, &count, shaders);'
-        print '        for (GLsizei i = 0; i < count; ++ i) {'
-        print '           writeShader(json, shaders[i]);'
-        print '        }'
-        print '        delete [] shaders;'
+        print '    const char *s = _enum_string(pname);'
+        print '    if (s) {'
+        print '        json.writeString(s);'
+        print '    } else {'
+        print '        json.writeNumber(pname);'
         print '    }'
-        print '    json.endArray();'
-        print '    json.endMember();'
-        print '    json.endObject();'
         print '}'
         print
 
+        # shaders
+        print '''
+static void
+writeShader(JSONWriter &json, GLuint shader)
+{
+    if (!shader) {
+        return;
+    }
+
+    GLint shader_type = 0;
+    glGetShaderiv(shader, GL_SHADER_TYPE, &shader_type);
+    if (!shader_type) {
+        return;
+    }
+
+    GLint source_length = 0;
+    glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &source_length);
+    if (!source_length) {
+        return;
+    }
+
+    GLchar *source = new GLchar[source_length];
+    GLsizei length = 0;
+    source[0] = 0;
+    glGetShaderSource(shader, source_length, &length, source);
+
+    json.beginMember(enum_string(shader_type));
+    json.writeString(source);
+    json.endMember();
+
+    delete [] source;
+}
+
+static inline void
+writeCurrentProgram(JSONWriter &json)
+{
+    GLint program = 0;
+    glGetIntegerv(GL_CURRENT_PROGRAM, &program);
+    if (!program) {
+        return;
+    }
+
+    GLint attached_shaders = 0;
+    glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
+    if (!attached_shaders) {
+        return;
+    }
+
+    GLuint *shaders = new GLuint[attached_shaders];
+    GLsizei count = 0;
+    glGetAttachedShaders(program, attached_shaders, &count, shaders);
+    for (GLsizei i = 0; i < count; ++ i) {
+       writeShader(json, shaders[i]);
+    }
+    delete [] shaders;
+}
+
+static inline void
+writeArbProgram(JSONWriter &json, GLenum target)
+{
+    if (!glIsEnabled(target)) {
+        return;
+    }
+
+    GLint program_length = 0;
+    glGetProgramivARB(target, GL_PROGRAM_LENGTH_ARB, &program_length);
+    if (!program_length) {
+        return;
+    }
+
+    GLchar *source = new GLchar[program_length + 1];
+    source[0] = 0;
+    glGetProgramStringARB(target, GL_PROGRAM_STRING_ARB, source);
+    source[program_length] = 0;
+
+    json.beginMember(enum_string(target));
+    json.writeString(source);
+    json.endMember();
+
+    delete [] source;
+}
+'''
+
         # texture image
         print '''
 static inline void
@@ -3260,36 +3326,38 @@ writeDrawBufferImage(JSONWriter &json, GLenum format)
     def dump_parameters(self):
         print '    json.beginMember("parameters");'
         print '    json.beginObject();'
-        for function, type, count, name in parameters:
-            if function != 'glGet':
-                continue
-            if type is X:
-                continue
-            if count != 1:
-                type = Array(type, str(count))
-
-            print '    // %s' % name
-            print '    {'
-            value = StateGetter(glGet).visit(type, name)
-            print '        if (glGetError() != GL_NO_ERROR) {'
-            #print '            std::cerr << "warning: %s(%s) failed\\n";' % (glGet.radical, name)
-            print '        } else {'
-            print '            json.beginMember("%s");' % name
-            JsonWriter().visit(type, value)
-            print '            json.endMember();'
-            print '        }'
-            print '    }'
-            print
+        
+        self.dump_atoms(glGet)
+        
+        self.dump_vertex_attribs()
+
         print '    json.endObject();'
         print '    json.endMember(); // parameters'
         print
 
+    def dump_vertex_attribs(self):
+        print '    json.beginMember("GL_VERTEX_ATTRIB");'
+        print '    json.beginArray();'
+        print '    GLint max_vertex_attribs = 0;'
+        print '    __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);'
+        print '    for (GLint index = 0; index < max_vertex_attribs; ++index) {'
+        print '        json.beginObject();'
+        self.dump_atoms(glGetVertexAttrib, 'index')
+        print '        json.endObject();'
+        print '    }'
+        print
+        print '    json.endArray();'
+        print '    json.endMember(); // GL_VERTEX_ATTRIB'
+        print
+
     def dump_current_program(self):
-        print '    GLint current_program = 0;'
-        print '    glGetIntegerv(GL_CURRENT_PROGRAM, &current_program);'
-        print '    json.beginMember("current_program");'
-        print '    writeProgram(json, current_program);'
-        print '    json.endMember();'
+        print '    json.beginMember("shaders");'
+        print '    json.beginObject();'
+        print '    writeCurrentProgram(json);'
+        print '    writeArbProgram(json, GL_FRAGMENT_PROGRAM_ARB);'
+        print '    writeArbProgram(json, GL_VERTEX_PROGRAM_ARB);'
+        print '    json.endObject();'
+        print '    json.endMember(); //shaders'
         print
 
     def dump_textures(self):
@@ -3342,6 +3410,25 @@ writeDrawBufferImage(JSONWriter &json, GLenum format)
         print '    json.endMember(); // framebuffer'
         pass
 
+    def dump_atoms(self, getter, *args):
+        for function, type, count, name in parameters:
+            if function != getter.inflector.radical:
+                continue
+            if type is X:
+                continue
+            print '        // %s' % name
+            print '        {'
+            type, value = getter(*(args + (name,)))
+            print '            if (glGetError() != GL_NO_ERROR) {'
+            #print '                std::cerr << "warning: %s(%s) failed\\n";' % (glGet.radical, name)
+            print '            } else {'
+            print '                json.beginMember("%s");' % name
+            JsonWriter().visit(type, value)
+            print '                json.endMember();'
+            print '            }'
+            print '        }'
+            print
+
     def write_line(s):
         self.write('  '*self.level + s + '\n')