}
+/**
+ * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
+ */
+static GLbitfield
+get_shader_flags(void)
+{
+ GLbitfield flags = 0x0;
+ const char *env = _mesa_getenv("MESA_GLSL");
+
+ if (env) {
+ if (_mesa_strstr(env, "dump"))
+ flags |= GLSL_DUMP;
+ if (_mesa_strstr(env, "log"))
+ flags |= GLSL_LOG;
+ if (_mesa_strstr(env, "nopt"))
+ flags |= GLSL_NO_OPT;
+ else if (_mesa_strstr(env, "opt"))
+ flags |= GLSL_OPT;
+ if (_mesa_strstr(env, "uniform"))
+ flags |= GLSL_UNIFORMS;
+ }
+
+ return flags;
+}
+
/**
* Initialize context's shader state.
ctx->Shader.EmitHighLevelInstructions = GL_TRUE;
ctx->Shader.EmitCondCodes = GL_FALSE;/*GL_TRUE;*/ /* XXX probably want GL_FALSE... */
ctx->Shader.EmitComments = GL_FALSE;
+ ctx->Shader.Flags = get_shader_flags();
}
if (!sh)
return;
- sh->CompileStatus = _slang_compile(ctx, sh);
+ /* this call will set the sh->CompileStatus field to indicate if
+ * compilation was successful.
+ */
+ (void) _slang_compile(ctx, sh);
}
/**
- * Update the vertex and fragment program's TexturesUsed arrays.
+ * Update the vertex/fragment program's TexturesUsed array.
+ *
+ * This needs to be called after glUniform(set sampler var) is called.
+ * A call to glUniform(samplerVar, value) causes a sampler to point to a
+ * particular texture unit. We know the sampler's texture target
+ * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
+ * set by glUniform() calls.
+ *
+ * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
+ * information to update the prog->TexturesUsed[] values.
+ * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
+ * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
+ * We'll use that info for state validation before rendering.
*/
-static void
-update_textures_used(struct gl_program *prog)
+void
+_mesa_update_shader_textures_used(struct gl_program *prog)
{
GLuint s;
GLenum type, GLsizei count, GLint elems,
const void *values)
{
+ struct gl_program_parameter *param =
+ &program->Parameters->Parameters[index];
+
assert(offset >= 0);
- if (!compatible_types(type,
- program->Parameters->Parameters[index].DataType)) {
+ if (!compatible_types(type, param->DataType)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
return;
}
return;
}
- if (program->Parameters->Parameters[index].Type == PROGRAM_SAMPLER) {
+ if (param->Type == PROGRAM_SAMPLER) {
/* This controls which texture unit which is used by a sampler */
GLuint texUnit, sampler;
/* This maps a sampler to a texture unit: */
program->SamplerUnits[sampler] = texUnit;
- update_textures_used(program);
+ _mesa_update_shader_textures_used(program);
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
}
else {
/* ordinary uniform variable */
GLsizei k, i;
- GLint slots = (program->Parameters->Parameters[index].Size + 3) / 4;
+ GLint slots = (param->Size + 3) / 4;
- if (count * elems > (GLint) program->Parameters->Parameters[index].Size) {
+ if (count * elems > (GLint) param->Size) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count too large)");
return;
}
count = slots;
for (k = 0; k < count; k++) {
- GLfloat *uniformVal = program->Parameters->ParameterValues[index + offset + k];
+ GLfloat *uniformVal =
+ program->Parameters->ParameterValues[index + offset + k];
if (is_integer_type(type)) {
const GLint *iValues = ((const GLint *) values) + k * elems;
for (i = 0; i < elems; i++) {
}
/* if the uniform is bool-valued, convert to 1.0 or 0.0 */
- if (is_boolean_type(program->Parameters->Parameters[index].DataType)) {
+ if (is_boolean_type(param->DataType)) {
for (i = 0; i < elems; i++) {
uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
}
const GLvoid *values, GLenum type)
{
struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+ struct gl_uniform *uniform;
GLint elems, offset;
+ GLenum basicType;
if (!shProg || !shProg->LinkStatus) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
switch (type) {
case GL_FLOAT:
+ basicType = GL_FLOAT;
+ elems = 1;
+ break;
case GL_INT:
+ basicType = GL_INT;
elems = 1;
break;
case GL_FLOAT_VEC2:
+ basicType = GL_FLOAT;
+ elems = 2;
+ break;
case GL_INT_VEC2:
+ basicType = GL_INT;
elems = 2;
break;
case GL_FLOAT_VEC3:
+ basicType = GL_FLOAT;
+ elems = 3;
+ break;
case GL_INT_VEC3:
+ basicType = GL_INT;
elems = 3;
break;
case GL_FLOAT_VEC4:
+ basicType = GL_FLOAT;
+ elems = 4;
+ break;
case GL_INT_VEC4:
+ basicType = GL_INT;
elems = 4;
break;
default:
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ uniform = &shProg->Uniforms->Uniforms[location];
+
+ if (ctx->Shader.Flags & GLSL_UNIFORMS) {
+ GLint i;
+ _mesa_printf("Mesa: set program %u uniform %s (loc %d) to: ",
+ shProg->Name, uniform->Name, location);
+ if (basicType == GL_INT) {
+ const GLint *v = (const GLint *) values;
+ for (i = 0; i < count * elems; i++) {
+ _mesa_printf("%d ", v[i]);
+ }
+ }
+ else {
+ const GLfloat *v = (const GLfloat *) values;
+ for (i = 0; i < count * elems; i++) {
+ _mesa_printf("%g ", v[i]);
+ }
+ }
+ _mesa_printf("\n");
+ }
+
/* A uniform var may be used by both a vertex shader and a fragment
* shader. We may need to update one or both shader's uniform here:
*/
if (shProg->VertexProgram) {
/* convert uniform location to program parameter index */
- GLint index = shProg->Uniforms->Uniforms[location].VertPos;
+ GLint index = uniform->VertPos;
if (index >= 0) {
set_program_uniform(ctx, &shProg->VertexProgram->Base,
index, offset, type, count, elems, values);
if (shProg->FragmentProgram) {
/* convert uniform location to program parameter index */
- GLint index = shProg->Uniforms->Uniforms[location].FragPos;
+ GLint index = uniform->FragPos;
if (index >= 0) {
set_program_uniform(ctx, &shProg->FragmentProgram->Base,
index, offset, type, count, elems, values);
}
}
+
+ uniform->Initialized = GL_TRUE;
}
GLenum matrixType, GLint location, GLsizei count,
GLboolean transpose, const GLfloat *values)
{
- GLint offset;
struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+ struct gl_uniform *uniform;
+ GLint offset;
if (!shProg || !shProg->LinkStatus) {
_mesa_error(ctx, GL_INVALID_OPERATION,
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ uniform = &shProg->Uniforms->Uniforms[location];
+
if (shProg->VertexProgram) {
/* convert uniform location to program parameter index */
- GLint index = shProg->Uniforms->Uniforms[location].VertPos;
+ GLint index = uniform->VertPos;
if (index >= 0) {
set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
index, offset,
if (shProg->FragmentProgram) {
/* convert uniform location to program parameter index */
- GLint index = shProg->Uniforms->Uniforms[location].FragPos;
+ GLint index = uniform->FragPos;
if (index >= 0) {
set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
index, offset,
count, rows, cols, transpose, values);
}
}
+
+ uniform->Initialized = GL_TRUE;
}