X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glstate.cpp;h=329276ffdf0b38e9ba8e91fcb9a36241b80c91c8;hb=a0e612d13d479d1b0e65d11037060b473c9d722f;hp=9d7845250423fc705daf50dbe76588e7b8099c6b;hpb=2cc9d302dcc858cadea7ee99da099396cf16518f;p=apitrace diff --git a/glstate.cpp b/glstate.cpp index 9d78452..329276f 100644 --- a/glstate.cpp +++ b/glstate.cpp @@ -121,8 +121,14 @@ getShaderObjSource(ShaderMap &shaderMap, GLhandleARB shaderObj) return; } + GLint object_type = 0; + glGetObjectParameterivARB(shaderObj, GL_OBJECT_TYPE_ARB, &object_type); + if (object_type != GL_SHADER_OBJECT_ARB) { + return; + } + GLint shader_type = 0; - glGetObjectParameterivARB(shaderObj, GL_OBJECT_TYPE_ARB, &shader_type); + glGetObjectParameterivARB(shaderObj, GL_OBJECT_SUBTYPE_ARB, &shader_type); if (!shader_type) { return; } @@ -145,14 +151,8 @@ getShaderObjSource(ShaderMap &shaderMap, GLhandleARB shaderObj) static inline void -dumpCurrentProgram(JSONWriter &json) +dumpProgram(JSONWriter &json, GLint program) { - 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) { @@ -179,15 +179,10 @@ dumpCurrentProgram(JSONWriter &json) static inline void -dumpCurrentProgramObj(JSONWriter &json) +dumpProgramObj(JSONWriter &json, GLhandleARB programObj) { - GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB); - if (!programObj) { - return; - } - GLint attached_shaders = 0; - glGetProgramivARB(programObj, GL_OBJECT_ATTACHED_OBJECTS_ARB, &attached_shaders); + glGetObjectParameterivARB(programObj, GL_OBJECT_ATTACHED_OBJECTS_ARB, &attached_shaders); if (!attached_shaders) { return; } @@ -210,10 +205,33 @@ dumpCurrentProgramObj(JSONWriter &json) } } +/* + * When fetching the uniform name of an array we usually get name[0] + * so we need to cut the trailing "[0]" in order to properly construct + * array names later. Otherwise we endup with stuff like + * uniformArray[0][0], + * uniformArray[0][1], + * instead of + * uniformArray[0], + * uniformArray[1]. + */ +static std::string +resolveUniformName(const GLchar *name, GLint size) +{ + std::string qualifiedName(name); + if (size > 1) { + std::string::size_type nameLength = qualifiedName.length(); + static const char * const arrayStart = "[0]"; + static const int arrayStartLen = 3; + if (qualifiedName.rfind(arrayStart) == (nameLength - arrayStartLen)) { + qualifiedName = qualifiedName.substr(0, nameLength - 3); + } + } + return qualifiedName; +} static void dumpUniform(JSONWriter &json, GLint program, GLint size, GLenum type, const GLchar *name) { - GLenum elemType; GLint numElems; __gl_uniform_size(type, elemType, numElems); @@ -228,9 +246,11 @@ dumpUniform(JSONWriter &json, GLint program, GLint size, GLenum type, const GLch GLint i, j; + std::string qualifiedName = resolveUniformName(name, size); + for (i = 0; i < size; ++i) { std::stringstream ss; - ss << name; + ss << qualifiedName; if (size > 1) { ss << '[' << i << ']'; @@ -291,15 +311,81 @@ dumpUniform(JSONWriter &json, GLint program, GLint size, GLenum type, const GLch } -static inline void -dumpCurrentProgramUniforms(JSONWriter &json) -{ - GLint program = 0; - glGetIntegerv(GL_CURRENT_PROGRAM, &program); - if (!program) { +static void +dumpUniformARB(JSONWriter &json, GLhandleARB programObj, GLint size, GLenum type, const GLchar *name) { + + GLenum elemType; + GLint numElems; + __gl_uniform_size(type, elemType, numElems); + if (elemType == GL_NONE) { return; } + GLfloat fvalues[4*4]; + GLint ivalues[4*4]; + + GLint i, j; + + std::string qualifiedName = resolveUniformName(name, size); + + for (i = 0; i < size; ++i) { + std::stringstream ss; + ss << qualifiedName; + + if (size > 1) { + ss << '[' << i << ']'; + } + + std::string elemName = ss.str(); + + json.beginMember(elemName); + + GLint location = glGetUniformLocationARB(programObj, elemName.c_str()); + + if (numElems > 1) { + json.beginArray(); + } + + switch (elemType) { + case GL_DOUBLE: + // glGetUniformdvARB does not exists + case GL_FLOAT: + glGetUniformfvARB(programObj, location, fvalues); + for (j = 0; j < numElems; ++j) { + json.writeNumber(fvalues[j]); + } + break; + case GL_UNSIGNED_INT: + // glGetUniformuivARB does not exists + case GL_INT: + glGetUniformivARB(programObj, location, ivalues); + for (j = 0; j < numElems; ++j) { + json.writeNumber(ivalues[j]); + } + break; + case GL_BOOL: + glGetUniformivARB(programObj, location, ivalues); + for (j = 0; j < numElems; ++j) { + json.writeBool(ivalues[j]); + } + break; + default: + assert(0); + break; + } + + if (numElems > 1) { + json.endArray(); + } + + json.endMember(); + } +} + + +static inline void +dumpProgramUniforms(JSONWriter &json, GLint program) +{ GLint active_uniforms = 0; glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &active_uniforms); if (!active_uniforms) { @@ -326,6 +412,35 @@ dumpCurrentProgramUniforms(JSONWriter &json) } +static inline void +dumpProgramObjUniforms(JSONWriter &json, GLhandleARB programObj) +{ + GLint active_uniforms = 0; + glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &active_uniforms); + if (!active_uniforms) { + return; + } + + GLint active_uniform_max_length = 0; + glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, &active_uniform_max_length); + GLchar *name = new GLchar[active_uniform_max_length]; + if (!name) { + return; + } + + for (GLint index = 0; index < active_uniforms; ++index) { + GLsizei length = 0; + GLint size = 0; + GLenum type = GL_NONE; + glGetActiveUniformARB(programObj, index, active_uniform_max_length, &length, &size, &type, name); + + dumpUniformARB(json, programObj, size, type, name); + } + + delete [] name; +} + + static inline void dumpArbProgram(JSONWriter &json, GLenum target) { @@ -353,25 +468,97 @@ dumpArbProgram(JSONWriter &json, GLenum target) static inline void -dumpShaders(JSONWriter &json) +dumpArbProgramUniforms(JSONWriter &json, GLenum target, const char *prefix) { - json.beginMember("shaders"); - json.beginObject(); - dumpCurrentProgram(json); - dumpCurrentProgramObj(json); - dumpArbProgram(json, GL_FRAGMENT_PROGRAM_ARB); - dumpArbProgram(json, GL_VERTEX_PROGRAM_ARB); - json.endObject(); - json.endMember(); // shaders + if (!glIsEnabled(target)) { + return; + } + + GLint program_parameters = 0; + glGetProgramivARB(target, GL_PROGRAM_PARAMETERS_ARB, &program_parameters); + if (!program_parameters) { + return; + } + + GLint max_program_local_parameters = 0; + glGetProgramivARB(target, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &max_program_local_parameters); + for (GLint index = 0; index < max_program_local_parameters; ++index) { + GLdouble params[4] = {0, 0, 0, 0}; + glGetProgramLocalParameterdvARB(target, index, params); + + if (!params[0] && !params[1] && !params[2] && !params[3]) { + continue; + } + + char name[256]; + snprintf(name, sizeof name, "%sprogram.local[%i]", prefix, index); + + json.beginMember(name); + json.beginArray(); + json.writeNumber(params[0]); + json.writeNumber(params[1]); + json.writeNumber(params[2]); + json.writeNumber(params[3]); + json.endArray(); + json.endMember(); + } + + GLint max_program_env_parameters = 0; + glGetProgramivARB(target, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &max_program_env_parameters); + for (GLint index = 0; index < max_program_env_parameters; ++index) { + GLdouble params[4] = {0, 0, 0, 0}; + glGetProgramEnvParameterdvARB(target, index, params); + + if (!params[0] && !params[1] && !params[2] && !params[3]) { + continue; + } + + char name[256]; + snprintf(name, sizeof name, "%sprogram.env[%i]", prefix, index); + + json.beginMember(name); + json.beginArray(); + json.writeNumber(params[0]); + json.writeNumber(params[1]); + json.writeNumber(params[2]); + json.writeNumber(params[3]); + json.endArray(); + json.endMember(); + } } static inline void -dumpUniforms(JSONWriter &json) +dumpShadersUniforms(JSONWriter &json) { + GLint program = 0; + glGetIntegerv(GL_CURRENT_PROGRAM, &program); + + GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB); + + json.beginMember("shaders"); + json.beginObject(); + if (program) { + dumpProgram(json, program); + } else if (programObj) { + dumpProgramObj(json, programObj); + } else { + dumpArbProgram(json, GL_FRAGMENT_PROGRAM_ARB); + dumpArbProgram(json, GL_VERTEX_PROGRAM_ARB); + } + json.endObject(); + json.endMember(); // shaders + json.beginMember("uniforms"); json.beginObject(); - dumpCurrentProgramUniforms(json); + if (program) { + dumpProgramUniforms(json, program); + } else if (programObj) { + dumpProgramObjUniforms(json, programObj); + } else { + dumpArbProgramUniforms(json, GL_FRAGMENT_PROGRAM_ARB, "fp."); + dumpArbProgramUniforms(json, GL_VERTEX_PROGRAM_ARB, "vp."); + } json.endObject(); json.endMember(); // uniforms } @@ -381,6 +568,9 @@ static inline void dumpTextureImage(JSONWriter &json, GLenum target, GLint level) { GLint width, height = 1, depth = 1; + GLint format; + + glGetTexLevelParameteriv(target, level, GL_TEXTURE_INTERNAL_FORMAT, &format); width = 0; glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); @@ -401,7 +591,8 @@ dumpTextureImage(JSONWriter &json, GLenum target, GLint level) GLint active_texture = GL_TEXTURE0; glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); - snprintf(label, sizeof label, "%s, %s, level = %i", enumToString(active_texture), enumToString(target), level); + snprintf(label, sizeof label, "%s, %s, level = %d", + enumToString(active_texture), enumToString(target), level); json.beginMember(label); @@ -414,6 +605,8 @@ dumpTextureImage(JSONWriter &json, GLenum target, GLint level) json.writeNumberMember("__height__", height); json.writeNumberMember("__depth__", depth); + json.writeStringMember("__format__", enumToString(format)); + // Hardcoded for now, but we could chose types more adequate to the // texture internal format json.writeStringMember("__type__", "uint8"); @@ -431,7 +624,7 @@ dumpTextureImage(JSONWriter &json, GLenum target, GLint level) json.beginMember("__data__"); char *pngBuffer; int pngBufferSize; - Image::writePixelsToBuffer(pixels, width, height, 4, false, &pngBuffer, &pngBufferSize); + image::writePixelsToBuffer(pixels, width, height, 4, true, &pngBuffer, &pngBufferSize); json.writeBase64(pngBuffer, pngBufferSize); free(pngBuffer); json.endMember(); // __data__ @@ -545,6 +738,7 @@ getDrawableBounds(GLint *width, GLint *height) { #else +#if !TRACE_EGL Display *display; Drawable drawable; Window root; @@ -567,6 +761,9 @@ getDrawableBounds(GLint *width, GLint *height) { *width = w; *height = h; +#else + return false; +#endif #endif @@ -632,6 +829,25 @@ getTextureLevelSize(GLint texture, GLint level, GLint *width, GLint *height) } +static GLenum +getTextureLevelFormat(GLint texture, GLint level) +{ + GLenum target; + GLint bound_texture = 0; + if (!bindTexture(texture, target, bound_texture)) { + return GL_NONE; + } + + GLint format = GL_NONE; + glGetTexLevelParameteriv(target, level, GL_TEXTURE_INTERNAL_FORMAT, &format); + + glBindTexture(target, bound_texture); + + return format; +} + + + static bool getRenderbufferSize(GLint renderbuffer, GLint *width, GLint *height) { @@ -650,6 +866,22 @@ getRenderbufferSize(GLint renderbuffer, GLint *width, GLint *height) } +static GLenum +getRenderbufferFormat(GLint renderbuffer) +{ + GLint bound_renderbuffer = 0; + glGetIntegerv(GL_RENDERBUFFER_BINDING, &bound_renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + + GLint format = GL_NONE; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT, &format); + + glBindRenderbuffer(GL_RENDERBUFFER, bound_renderbuffer); + + return format; +} + + static bool getFramebufferAttachmentSize(GLenum target, GLenum attachment, GLint *width, GLint *height) { @@ -684,7 +916,43 @@ getFramebufferAttachmentSize(GLenum target, GLenum attachment, GLint *width, GLi } -Image::Image * + +static GLint +getFramebufferAttachmentFormat(GLenum target, GLenum attachment) +{ + GLint object_type = GL_NONE; + glGetFramebufferAttachmentParameteriv(target, attachment, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, + &object_type); + if (object_type == GL_NONE) { + return GL_NONE; + } + + GLint object_name = 0; + glGetFramebufferAttachmentParameteriv(target, attachment, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + &object_name); + if (object_name == 0) { + return GL_NONE; + } + + if (object_type == GL_RENDERBUFFER) { + return getRenderbufferFormat(object_name); + } else if (object_type == GL_TEXTURE) { + GLint texture_level = 0; + glGetFramebufferAttachmentParameteriv(target, attachment, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, + &texture_level); + return getTextureLevelFormat(object_name, texture_level); + } else { + std::cerr << "warning: unexpected GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = " << object_type << "\n"; + return GL_NONE; + } +} + + + +image::Image * getDrawBufferImage(GLenum format) { GLint channels = __gl_format_channels(format); if (channels > 4) { @@ -716,7 +984,7 @@ getDrawBufferImage(GLenum format) { } } - Image::Image *image = new Image::Image(width, height, channels, true); + image::Image *image = new image::Image(width, height, channels, true); if (!image) { return NULL; } @@ -758,7 +1026,8 @@ getDrawBufferImage(GLenum format) { * Dump the image of the currently bound read buffer. */ static inline void -dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format) +dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format, + GLint internalFormat = GL_NONE) { GLint channels = __gl_format_channels(format); @@ -771,6 +1040,8 @@ dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format) json.writeNumberMember("__height__", height); json.writeNumberMember("__depth__", 1); + json.writeStringMember("__format__", enumToString(internalFormat)); + // Hardcoded for now, but we could chose types more adequate to the // texture internal format json.writeStringMember("__type__", "uint8"); @@ -789,7 +1060,7 @@ dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format) json.beginMember("__data__"); char *pngBuffer; int pngBufferSize; - Image::writePixelsToBuffer(pixels, width, height, channels, false, &pngBuffer, &pngBufferSize); + image::writePixelsToBuffer(pixels, width, height, channels, true, &pngBuffer, &pngBufferSize); //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels) // <<", after = "<