#include "glheader.h"
#include "context.h"
#include "shaders.h"
+#include "shader/shader_api.h"
+
+
+/** Define this to enable shader substitution (see below) */
+#define SHADER_SUBST 0
+
/**
}
+
+/**
+ * Read shader source code from a file.
+ * Useful for debugging to override an app's shader.
+ */
+static GLcharARB *
+_mesa_read_shader(const char *fname)
+{
+ const int max = 50*1000;
+ FILE *f = fopen(fname, "r");
+ GLcharARB *buffer, *shader;
+ int len;
+
+ if (!f) {
+ return NULL;
+ }
+
+ buffer = (char *) malloc(max);
+ len = fread(buffer, 1, max, f);
+ buffer[len] = 0;
+
+ fclose(f);
+
+ shader = _mesa_strdup(buffer);
+ free(buffer);
+
+ return shader;
+}
+
+
/**
* Called via glShaderSource() and glShaderSourceARB() API functions.
* Basically, concatenate the source code strings into one long string
GLint *offsets;
GLsizei i, totalLength;
GLcharARB *source;
+ GLuint checksum;
if (!shaderObj || string == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
source[totalLength - 1] = '\0';
source[totalLength - 2] = '\0';
+ if (SHADER_SUBST) {
+ /* Compute the shader's source code checksum then try to open a file
+ * named newshader_<CHECKSUM>. If it exists, use it in place of the
+ * original shader source code. For debugging.
+ */
+ char filename[100];
+ GLcharARB *newSource;
+
+ checksum = _mesa_str_checksum(source);
+
+ sprintf(filename, "newshader_%d", checksum);
+
+ newSource = _mesa_read_shader(filename);
+ if (newSource) {
+ _mesa_fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
+ shaderObj, checksum, filename);
+ _mesa_free(source);
+ source = newSource;
+ }
+ }
+
ctx->Driver.ShaderSource(ctx, shaderObj, source);
+ if (SHADER_SUBST) {
+ struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
+ if (sh)
+ sh->SourceChecksum = checksum; /* save original checksum */
+ }
+
_mesa_free(offsets);
}
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Driver.UniformMatrix(ctx, 2, 2, GL_FLOAT_MAT2,
- location, count, transpose, value);
+ ctx->Driver.UniformMatrix(ctx, 2, 2, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Driver.UniformMatrix(ctx, 3, 3, GL_FLOAT_MAT3,
- location, count, transpose, value);
+ ctx->Driver.UniformMatrix(ctx, 3, 3, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Driver.UniformMatrix(ctx, 4, 4, GL_FLOAT_MAT4,
- location, count, transpose, value);
+ ctx->Driver.UniformMatrix(ctx, 4, 4, location, count, transpose, value);
}
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Driver.UniformMatrix(ctx, 2, 3, GL_FLOAT_MAT2x3,
- location, count, transpose, value);
+ ctx->Driver.UniformMatrix(ctx, 2, 3, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Driver.UniformMatrix(ctx, 3, 2, GL_FLOAT_MAT3x2,
- location, count, transpose, value);
+ ctx->Driver.UniformMatrix(ctx, 3, 2, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Driver.UniformMatrix(ctx, 2, 4, GL_FLOAT_MAT2x4,
- location, count, transpose, value);
+ ctx->Driver.UniformMatrix(ctx, 2, 4, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Driver.UniformMatrix(ctx, 4, 2, GL_FLOAT_MAT4x2,
- location, count, transpose, value);
+ ctx->Driver.UniformMatrix(ctx, 4, 2, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Driver.UniformMatrix(ctx, 3, 4, GL_FLOAT_MAT3x4,
- location, count, transpose, value);
+ ctx->Driver.UniformMatrix(ctx, 3, 4, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Driver.UniformMatrix(ctx, 4, 3, GL_FLOAT_MAT4x3,
- location, count, transpose, value);
+ ctx->Driver.UniformMatrix(ctx, 4, 3, location, count, transpose, value);
}