summaryrefslogtreecommitdiffstats
path: root/src/mesa/shader
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/shader')
-rw-r--r--src/mesa/shader/prog_parameter.c3
-rw-r--r--src/mesa/shader/slang/slang_emit.c8
-rw-r--r--src/mesa/shader/slang/slang_link.c57
3 files changed, 50 insertions, 18 deletions
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
index c0602ad2c94..dc48e84ab29 100644
--- a/src/mesa/shader/prog_parameter.c
+++ b/src/mesa/shader/prog_parameter.c
@@ -290,7 +290,8 @@ _mesa_use_uniform(struct gl_program_parameter_list *paramList,
GLuint i;
for (i = 0; i < paramList->NumParameters; i++) {
struct gl_program_parameter *p = paramList->Parameters + i;
- if (p->Type == PROGRAM_UNIFORM && _mesa_strcmp(p->Name, name) == 0) {
+ if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) &&
+ _mesa_strcmp(p->Name, name) == 0) {
p->Used = GL_TRUE;
/* Note that large uniforms may occupy several slots so we're
* not done searching yet.
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 500112b6f67..b7a3cfb6177 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -1290,6 +1290,7 @@ emit_tex(slang_emit_info *emitInfo, slang_ir_node *n)
/* Child[0] is the sampler (a uniform which'll indicate the texture unit) */
assert(n->Children[0]->Store);
+ assert(n->Children[0]->Store->File == PROGRAM_SAMPLER);
/* Store->Index is the sampler index */
assert(n->Children[0]->Store->Index >= 0);
/* Store->Size is the texture target */
@@ -1299,6 +1300,10 @@ emit_tex(slang_emit_info *emitInfo, slang_ir_node *n)
inst->TexSrcTarget = n->Children[0]->Store->Size;
inst->TexSrcUnit = n->Children[0]->Store->Index; /* i.e. uniform's index */
+ /* mark the sampler as being used */
+ _mesa_use_uniform(emitInfo->prog->Parameters,
+ (char *) n->Children[0]->Var->a_name);
+
return inst;
}
@@ -2104,7 +2109,8 @@ emit_var_ref(slang_emit_info *emitInfo, slang_ir_node *n)
n->Store->Index = index;
}
- else if (n->Store->File == PROGRAM_UNIFORM) {
+ else if (n->Store->File == PROGRAM_UNIFORM ||
+ n->Store->File == PROGRAM_SAMPLER) {
/* mark var as used */
_mesa_use_uniform(emitInfo->prog->Parameters, (char *) n->Var->a_name);
}
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index b49fd0e99d3..b2fd9554a66 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -1,8 +1,9 @@
/*
* Mesa 3-D graphics library
- * Version: 7.2
+ * Version: 7.3
*
* Copyright (C) 2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -206,6 +207,19 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
* Build the shProg->Uniforms list.
* This is basically a list/index of all uniforms found in either/both of
* the vertex and fragment shaders.
+ *
+ * About uniforms:
+ * Each uniform has two indexes, one that points into the vertex
+ * program's parameter array and another that points into the fragment
+ * program's parameter array. When the user changes a uniform's value
+ * we have to change the value in the vertex and/or fragment program's
+ * parameter array.
+ *
+ * This function will be called twice to set up the two uniform->parameter
+ * mappings.
+ *
+ * If a uniform is only present in the vertex program OR fragment program
+ * then the fragment/vertex parameter index, respectively, will be -1.
*/
static GLboolean
link_uniform_vars(GLcontext *ctx,
@@ -213,7 +227,7 @@ link_uniform_vars(GLcontext *ctx,
struct gl_program *prog,
GLuint *numSamplers)
{
- GLuint samplerMap[MAX_SAMPLERS];
+ GLuint samplerMap[200]; /* max number of samplers declared, not used */
GLuint i;
for (i = 0; i < prog->Parameters->NumParameters; i++) {
@@ -228,33 +242,41 @@ link_uniform_vars(GLcontext *ctx,
* Furthermore, we'll need to fix the state-var's size/datatype info.
*/
- if ((p->Type == PROGRAM_UNIFORM && p->Used) ||
- p->Type == PROGRAM_SAMPLER) {
+ if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER)
+ && p->Used) {
+ /* add this uniform, indexing into the target's Parameters list */
struct gl_uniform *uniform =
_mesa_append_uniform(shProg->Uniforms, p->Name, prog->Target, i);
if (uniform)
uniform->Initialized = p->Initialized;
}
- if (p->Type == PROGRAM_SAMPLER) {
+ /* The samplerMap[] table we build here is used to remap/re-index
+ * sampler references by TEX instructions.
+ */
+ if (p->Type == PROGRAM_SAMPLER && p->Used) {
/* Allocate a new sampler index */
- GLuint sampNum = *numSamplers;
GLuint oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0];
- if (oldSampNum >= ctx->Const.MaxTextureImageUnits) {
+ GLuint newSampNum = *numSamplers;
+ if (newSampNum >= ctx->Const.MaxTextureImageUnits) {
char s[100];
sprintf(s, "Too many texture samplers (%u, max is %u)",
- oldSampNum + 1, ctx->Const.MaxTextureImageUnits);
+ newSampNum, ctx->Const.MaxTextureImageUnits);
link_error(shProg, s);
return GL_FALSE;
}
- samplerMap[oldSampNum] = sampNum;
+ /* save old->new mapping in the table */
+ if (oldSampNum < Elements(samplerMap))
+ samplerMap[oldSampNum] = newSampNum;
+ /* update parameter's sampler index */
+ prog->Parameters->ParameterValues[i][0] = (GLfloat) newSampNum;
(*numSamplers)++;
}
}
-
- /* OK, now scan the program/shader instructions looking for sampler vars,
- * replacing the old index with the new index.
+ /* OK, now scan the program/shader instructions looking for texture
+ * instructions using sampler vars. Replace old sampler indexes with
+ * new ones.
*/
prog->SamplersUsed = 0x0;
for (i = 0; i < prog->NumInstructions; i++) {
@@ -265,10 +287,13 @@ link_uniform_vars(GLcontext *ctx,
inst->Sampler, map[ inst->Sampler ]);
*/
/* here, texUnit is really samplerUnit */
- assert(inst->TexSrcUnit < MAX_SAMPLERS);
- inst->TexSrcUnit = samplerMap[inst->TexSrcUnit];
- prog->SamplerTargets[inst->TexSrcUnit] = inst->TexSrcTarget;
- prog->SamplersUsed |= (1 << inst->TexSrcUnit);
+ const GLint oldSampNum = inst->TexSrcUnit;
+ if (oldSampNum < Elements(samplerMap)) {
+ const GLuint newSampNum = samplerMap[oldSampNum];
+ inst->TexSrcUnit = newSampNum;
+ prog->SamplerTargets[newSampNum] = inst->TexSrcTarget;
+ prog->SamplersUsed |= (1 << newSampNum);
+ }
}
}