gltrace: Patch up all glUniform*() calls.

This patch updates the trace information for all glUniform*() calls
to have the right data (the actual uniforms that are passed).

In addition, as soon as a program is linked, information regarding
all the active attributes and uniforms is passed on to the debugger.

Change-Id: Icfbc6722789b42c413a845cf546577fa6de7da2b
This commit is contained in:
Siva Velusamy 2012-02-14 15:08:20 -08:00
parent fbaf70abed
commit 88e8e5a3f1

View File

@ -15,9 +15,13 @@
*/
#include <cutils/log.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include "gltrace.pb.h"
#include "gltrace_api.h"
#include "gltrace_context.h"
#include "gltrace_fixup.h"
@ -198,6 +202,20 @@ void fixup_glShaderSource(GLMessage *glmsg) {
arg_strpp->add_charvalue(src);
}
void fixup_glUniformGenericInteger(int argIndex, int nIntegers, GLMessage *glmsg) {
/* void glUniform?iv(GLint location, GLsizei count, const GLint *value); */
GLMessage_DataType *arg_values = glmsg->mutable_args(argIndex);
GLint *src = (GLint*)arg_values->intvalue(0);
arg_values->set_type(GLMessage::DataType::INT);
arg_values->set_isarray(true);
arg_values->clear_intvalue();
for (int i = 0; i < nIntegers; i++) {
arg_values->add_intvalue(*src++);
}
}
void fixup_glUniformGeneric(int argIndex, int nFloats, GLMessage *glmsg) {
GLMessage_DataType *arg_values = glmsg->mutable_args(argIndex);
GLfloat *src = (GLfloat*)arg_values->intvalue(0);
@ -223,6 +241,10 @@ void fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg) {
GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex);
GLint *intp = (GLint *)arg_intarray->intvalue(0);
if (intp == NULL) {
return;
}
arg_intarray->set_type(GLMessage::DataType::INT);
arg_intarray->set_isarray(true);
arg_intarray->clear_intvalue();
@ -232,6 +254,15 @@ void fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg) {
}
}
void fixup_GenericEnumArray(int argIndex, int nEnums, GLMessage *glmsg) {
// fixup as if they were ints
fixup_GenericIntArray(argIndex, nEnums, glmsg);
// and then set the data type to be enum
GLMessage_DataType *arg_enumarray = glmsg->mutable_args(argIndex);
arg_enumarray->set_type(GLMessage::DataType::ENUM);
}
void fixup_glGenGeneric(GLMessage *glmsg) {
/* void glGen*(GLsizei n, GLuint * buffers); */
GLMessage_DataType arg_n = glmsg->args(0);
@ -270,6 +301,84 @@ void fixup_glGetFloatv(GLMessage *glmsg) {
arg_params->add_floatvalue(*src);
}
void fixup_glLinkProgram(GLMessage *glmsg) {
/* void glLinkProgram(GLuint program); */
GLuint program = glmsg->args(0).intvalue(0);
/* We don't have to fixup this call, but as soon as a program is linked,
we obtain information about all active attributes and uniforms to
pass on to the debugger. Note that in order to pass this info to
the debugger, all we need to do is call the trace versions of the
necessary calls. */
GLint n, maxNameLength;
GLchar *name;
GLint size;
GLenum type;
// obtain info regarding active attributes
GLTrace_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
GLTrace_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength);
name = (GLchar *) malloc(maxNameLength);
for (int i = 0; i < n; i++) {
GLTrace_glGetActiveAttrib(program, i, maxNameLength, NULL, &size, &type, name);
}
free(name);
// obtain info regarding active uniforms
GLTrace_glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
GLTrace_glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
name = (GLchar *) malloc(maxNameLength);
for (int i = 0; i < n; i++) {
GLTrace_glGetActiveUniform(program, i, maxNameLength, NULL, &size, &type, name);
}
free(name);
}
/** Given a glGetActive[Uniform|Attrib] call, obtain the location
* of the variable in the call.
*/
int getShaderVariableLocation(GLTraceContext *context, GLMessage *glmsg) {
GLMessage_Function func = glmsg->function();
if (func != GLMessage::glGetActiveAttrib && func != GLMessage::glGetActiveUniform) {
return -1;
}
int program = glmsg->args(0).intvalue(0);
GLchar *name = (GLchar*) glmsg->args(6).intvalue(0);
if (func == GLMessage::glGetActiveAttrib) {
return context->hooks->gl.glGetAttribLocation(program, name);
} else {
return context->hooks->gl.glGetUniformLocation(program, name);
}
}
void fixup_glGetActiveAttribOrUniform(GLMessage *glmsg, int location) {
/* void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
GLsizei* length, GLint* size, GLenum* type, GLchar* name); */
/* void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
GLsizei* length, GLint* size, GLenum* type, GLchar* name) */
fixup_GenericIntArray(3, 1, glmsg); // length
fixup_GenericIntArray(4, 1, glmsg); // size
fixup_GenericEnumArray(5, 1, glmsg); // type
fixup_CStringPtr(6, glmsg); // name
// The index argument in the glGetActive[Attrib|Uniform] functions
// does not correspond to the actual location index as used in
// glUniform*() or glVertexAttrib*() to actually upload the data.
// In order to make things simpler for the debugger, we also pass
// a hidden location argument that stores the actual location.
// append the location value to the end of the argument list
GLMessage_DataType *arg_location = glmsg->add_args();
arg_location->set_isarray(false);
arg_location->set_type(GLMessage::DataType::INT);
arg_location->add_intvalue(location);
}
void fixupGLMessage(GLTraceContext *context, nsecs_t start, nsecs_t end, GLMessage *glmsg) {
// for all messages, set the current context id
glmsg->set_context_id(context->getId());
@ -292,6 +401,19 @@ void fixupGLMessage(GLTraceContext *context, nsecs_t start, nsecs_t end, GLMessa
case GLMessage::glGenTextures: /* void glGenTextures(GLsizei n, GLuint *textures); */
fixup_glGenGeneric(glmsg);
break;
case GLMessage::glLinkProgram: /* void glLinkProgram(GLuint program); */
fixup_glLinkProgram(glmsg);
break;
case GLMessage::glGetActiveAttrib:
fixup_glGetActiveAttribOrUniform(glmsg, getShaderVariableLocation(context, glmsg));
break;
case GLMessage::glGetActiveUniform:
fixup_glGetActiveAttribOrUniform(glmsg, getShaderVariableLocation(context, glmsg));
break;
case GLMessage::glBindAttribLocation:
/* void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name); */
fixup_CStringPtr(2, glmsg);
break;
case GLMessage::glGetAttribLocation:
case GLMessage::glGetUniformLocation:
/* int glGetAttribLocation(GLuint program, const GLchar* name) */
@ -331,6 +453,38 @@ void fixupGLMessage(GLTraceContext *context, nsecs_t start, nsecs_t end, GLMessa
case GLMessage::glShaderSource:
fixup_glShaderSource(glmsg);
break;
case GLMessage::glUniform1iv:
/* void glUniform1iv(GLint location, GLsizei count, const GLint *value); */
fixup_glUniformGenericInteger(2, 1, glmsg);
break;
case GLMessage::glUniform2iv:
/* void glUniform2iv(GLint location, GLsizei count, const GLint *value); */
fixup_glUniformGenericInteger(2, 2, glmsg);
break;
case GLMessage::glUniform3iv:
/* void glUniform3iv(GLint location, GLsizei count, const GLint *value); */
fixup_glUniformGenericInteger(2, 3, glmsg);
break;
case GLMessage::glUniform4iv:
/* void glUniform4iv(GLint location, GLsizei count, const GLint *value); */
fixup_glUniformGenericInteger(2, 4, glmsg);
break;
case GLMessage::glUniform1fv:
/* void glUniform1fv(GLint location, GLsizei count, const GLfloat *value); */
fixup_glUniformGeneric(2, 1, glmsg);
break;
case GLMessage::glUniform2fv:
/* void glUniform2fv(GLint location, GLsizei count, const GLfloat *value); */
fixup_glUniformGeneric(2, 2, glmsg);
break;
case GLMessage::glUniform3fv:
/* void glUniform3fv(GLint location, GLsizei count, const GLfloat *value); */
fixup_glUniformGeneric(2, 3, glmsg);
break;
case GLMessage::glUniform4fv:
/* void glUniform4fv(GLint location, GLsizei count, const GLfloat *value); */
fixup_glUniformGeneric(2, 4, glmsg);
break;
case GLMessage::glUniformMatrix2fv:
/* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat* value) */