X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glstate.py;h=0caba470130f7fbe10f2a6520684f70cf305a0b1;hb=448d423ce3dc6eea8af166b366687c24825b6e2b;hp=6c6f25988e1246eb5f6e38532a50a8e5ac380cd2;hpb=7691c22fea21a1d8a4fbdcbd0d1fbf2324604e6c;p=apitrace diff --git a/glstate.py b/glstate.py index 6c6f259..0caba47 100644 --- a/glstate.py +++ b/glstate.py @@ -26,15 +26,15 @@ from stdapi import * -from glenum import GLenum +from glapi import * X = None # To be determined -B = Bool -I = Int +B = GLboolean +I = GLint E = GLenum -F = Float -D = Double +F = GLfloat +D = GLdouble P = OpaquePointer(Void) S = CString @@ -1346,7 +1346,7 @@ parameters = [ ("glGet", X, 1, "GL_SLICE_ACCUM_SUN"), # 0x85CC ("glGet", X, 1, "GL_QUAD_MESH_SUN"), # 0x8614 ("glGet", X, 1, "GL_TRIANGLE_MESH_SUN"), # 0x8615 - ("glGet", X, 1, "GL_VERTEX_PROGRAM_ARB"), # 0x8620 + ("glGet", B, 1, "GL_VERTEX_PROGRAM_ARB"), # 0x8620 ("glGet", X, 1, "GL_VERTEX_STATE_PROGRAM_NV"), # 0x8621 ("glGetVertexAttrib", B, 1, "GL_VERTEX_ATTRIB_ARRAY_ENABLED"), # 0x8622 ("glGetVertexAttrib", I, 1, "GL_VERTEX_ATTRIB_ARRAY_SIZE"), # 0x8623 @@ -1360,8 +1360,8 @@ parameters = [ ("glGet", X, 1, "GL_INVERSE_NV"), # 0x862B ("glGet", X, 1, "GL_TRANSPOSE_NV"), # 0x862C ("glGet", X, 1, "GL_INVERSE_TRANSPOSE_NV"), # 0x862D - ("glGet", X, 1, "GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB"), # 0x862E - ("glGet", X, 1, "GL_MAX_PROGRAM_MATRICES_ARB"), # 0x862F + ("glGet", I, 1, "GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB"), # 0x862E + ("glGet", I, 1, "GL_MAX_PROGRAM_MATRICES_ARB"), # 0x862F ("glGet", X, 1, "GL_MATRIX0_NV"), # 0x8630 ("glGet", X, 1, "GL_MATRIX1_NV"), # 0x8631 ("glGet", X, 1, "GL_MATRIX2_NV"), # 0x8632 @@ -1372,8 +1372,8 @@ parameters = [ ("glGet", X, 1, "GL_MATRIX7_NV"), # 0x8637 ("glGet", X, 1, "GL_CURRENT_MATRIX_STACK_DEPTH_ARB"), # 0x8640 ("glGet", X, 1, "GL_CURRENT_MATRIX_ARB"), # 0x8641 - ("glGet", X, 1, "GL_VERTEX_PROGRAM_POINT_SIZE"), # 0x8642 - ("glGet", X, 1, "GL_VERTEX_PROGRAM_TWO_SIDE"), # 0x8643 + ("glGet", B, 1, "GL_VERTEX_PROGRAM_POINT_SIZE"), # 0x8642 + ("glGet", B, 1, "GL_VERTEX_PROGRAM_TWO_SIDE"), # 0x8643 ("glGet", X, 1, "GL_PROGRAM_PARAMETER_NV"), # 0x8644 ("glGetVertexAttrib", P, 1, "GL_VERTEX_ATTRIB_ARRAY_POINTER"), # 0x8645 ("glGet", X, 1, "GL_PROGRAM_TARGET_NV"), # 0x8646 @@ -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 @@ -1850,7 +1850,7 @@ parameters = [ ("glGet", I, 1, "GL_MAX_TEXTURE_COORDS"), # 0x8871 ("glGet", I, 1, "GL_MAX_TEXTURE_IMAGE_UNITS"), # 0x8872 ("glGet", I, 1, "GL_FRAGMENT_PROGRAM_BINDING_NV"), # 0x8873 - ("glGet", X, 1, "GL_PROGRAM_ERROR_STRING_ARB"), # 0x8874 + ("glGet", S, 1, "GL_PROGRAM_ERROR_STRING_ARB"), # 0x8874 ("glGet", X, 1, "GL_PROGRAM_FORMAT_ASCII_ARB"), # 0x8875 ("glGet", X, 1, "GL_PROGRAM_FORMAT_ARB"), # 0x8876 ("glGet", X, 1, "GL_WRITE_PIXEL_DATA_RANGE_NV"), # 0x8878 @@ -2837,67 +2837,112 @@ texture_targets = [ ] -class GlGetter(Visitor): - '''Type visitor - Determine which glGet*v function that matches the specified type.''' +class GetInflector: + '''Objects that describes how to inflect.''' - def __init__(self, prefix = 'glGet', long_suffix = True): - self.prefix = prefix - self.long_suffix = long_suffix + reduced_types = { + B: I, + E: I, + I: F, + } - if prefix == 'glGet': - self.suffixes = { - 'GLboolean': 'Booleanv', - 'GLint': 'Intv', - 'GLfloat': 'Floatv', - 'GLdouble': 'Doublev', - 'GLstring': 'String', - } - else: - self.suffixes = { - 'GLint': 'iv', - 'GLfloat': 'fv', - 'GLdouble': 'Doublev', - 'GLstring': 'String', - } - - - def visit_const(self, const): - return self.visit(const.type) - - def visit_alias(self, alias): - if alias.expr == 'GLboolean': - if self.long_suffix: - return self.prefix + 'Booleanv', alias.expr - else: - return self.prefix + 'iv', 'GLint' - elif alias.expr == 'GLdouble': - if self.long_suffix: - return self.prefix + 'Doublev', alias.expr - else: - return self.prefix + 'dv', alias.expr - elif alias.expr == 'GLfloat': - if self.long_suffix: - return self.prefix + 'Floatv', alias.expr - else: - return self.prefix + 'fv', alias.expr - elif alias.expr in ('GLint', 'GLuint', 'GLsizei'): - if self.long_suffix: - return self.prefix + 'Integerv', 'GLint' - else: - return self.prefix + 'iv', 'GLint' - else: - print alias.expr - assert False - - def visit_enum(self, enum): - return self.visit(glapi.GLint) + def __init__(self, radical, suffixes): + self.radical = radical + self.suffixes = suffixes + + def reduced_type(self, type): + if type in self.suffixes: + return type + if type in self.reduced_types: + return self.reduced_type(self.reduced_types[type]) + raise NotImplementedError + + def inflect(self, type): + return self.radical + self.suffix(type) + + def suffix(self, type): + type = self.reduced_type(type) + assert type in self.suffixes + 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'}) - def visit_bitmask(self, bitmask): - return self.visit(glapi.GLint) - def visit_opaque(self, pointer): - return self.prefix + 'Pointerv', 'GLvoid *' + +class StateGetter(Visitor): + '''Type visitor that is able to extract the state via one of the glGet* + functions. + + It will declare any temporary variable + ''' + + def __init__(self, inflector): + self.inflector = inflector + + def temp_name(self, pname): + '''Return the name of a temporary variable to hold the state.''' + + return pname[3:].lower() + + def visit_const(self, const, pname): + return self.visit(const.type, pname) + + def visit_scalar(self, type, pname): + temp_name = self.temp_name(pname) + 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) + else: + print ' %s %s = %s(%s);' % (elem_type, temp_name, inflection, pname) + return temp_name + + def visit_string(self, string, pname): + temp_name = self.temp_name(pname) + inflection = self.inflector.inflect(string) + assert not inflection.endswith('v') + print ' %s %s = (%s)%s(%s);' % (string, temp_name, string, inflection, pname) + return temp_name + + def visit_alias(self, alias, pname): + return self.visit_scalar(alias, pname) + + def visit_enum(self, enum, pname): + return self.visit(GLint, pname) + + def visit_bitmask(self, bitmask, pname): + return self.visit(GLint, pname) + + def visit_array(self, array, pname): + temp_name = self.temp_name(pname) + if array.length == '1': + return self.visit(array.type) + elem_type = self.inflector.reduced_type(array.type) + inflection = self.inflector.inflect(array.type) + 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) + return temp_name + + def visit_opaque(self, pointer, pname): + temp_name = self.temp_name(pname) + inflection = self.inflector.inflect(pointer) + assert inflection.endswith('v') + print ' GLvoid *%s;' % temp_name + print ' %s(%s, &%s);' % (inflection, pname, temp_name) + return temp_name class JsonWriter(Visitor): @@ -2947,6 +2992,8 @@ class JsonWriter(Visitor): class StateDumper: + '''Class to generate code to dump all GL state in JSON format via + stdout.''' def __init__(self): self.level = 0 @@ -2962,77 +3009,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 @@ -3211,15 +3309,6 @@ writeDrawBufferImage(JSONWriter &json, GLenum format) print def dump_parameters(self): - print ' const GLubyte * sparams[1];' - print ' GLboolean bparams[16];' - print ' GLint iparams[16];' - print ' GLfloat fparams[16];' - print ' GLdouble dparams[16];' - print ' GLvoid * pparams[16];' - print - print ' (void)dparams;' - print print ' json.beginMember("parameters");' print ' json.beginObject();' for function, type, count, name in parameters: @@ -3227,55 +3316,33 @@ writeDrawBufferImage(JSONWriter &json, GLenum format) continue if type is X: continue - elif type is B: - buf = 'bparams' - getter = 'glGetBooleanv' - elif type is I: - buf = 'iparams' - getter = 'glGetIntegerv' - elif type is E: - buf = 'iparams' - getter = 'glGetIntegerv' - elif type is F: - buf = 'fparams' - getter = 'glGetFloatv' - elif type is D: - buf = 'dparams' - getter = 'glGetDoublev' - elif type is P: - buf = 'pparams' - getter = 'glGetPointerv' - elif type is S: - buf = 'sparams' - getter = 'glGetString' - else: - raise NotImplementedError - print ' memset(%s, 0, %u * sizeof *%s);' % (buf, count, buf) - if getter.endswith('v'): - print ' %s(%s, %s);' % (getter, name, buf) - else: - assert count == 1 - print ' %s[0] = %s(%s);' % (buf, getter, name) - print ' if (glGetError() != GL_NO_ERROR) {' - #print ' std::cerr << "warning: %s(%s) failed\\n";' % (getter, name) - print ' } else {' - print ' json.beginMember("%s");' % name - if count == 1: - JsonWriter().visit(type, '%s[0]' % buf) - else: - JsonWriter().visit(Array(type, str(count)), buf) - print ' json.endMember();' + 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 print ' json.endObject();' print ' json.endMember(); // parameters' print def dump_current_program(self): - print ' GLint current_program = 0;' - print ' glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_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):