summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Rusin <zack@tungstengraphics.com>2008-06-12 18:53:52 -0400
committerZack Rusin <zack@tungstengraphics.com>2008-06-12 19:04:28 -0400
commit3911ef032745b18071f48a6ad343ece14202049c (patch)
tree89778ffbe0346b99c831506191cce20244b26573
parente961a5da77cbcdb0e32400ec707c16fcfe9d7083 (diff)
glsl: make sure we replace all output reads with temporaries
test in if.glsl
-rw-r--r--src/mesa/shader/programopt.c12
-rw-r--r--src/mesa/shader/programopt.h2
-rw-r--r--src/mesa/shader/slang/slang_compile.c3
3 files changed, 10 insertions, 7 deletions
diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c
index 7d560c74a5..da4e3fcfcf 100644
--- a/src/mesa/shader/programopt.c
+++ b/src/mesa/shader/programopt.c
@@ -367,20 +367,22 @@ _mesa_count_texture_instructions(struct gl_program *prog)
/**
- * Scan/rewrite program to remove reads of varying (output) registers.
+ * Scan/rewrite program to remove reads of custom (output) registers.
+ * The passed type has to be either PROGRAM_VARYING or PROGRAM_OUTPUT.
* In GLSL vertex shaders, varying vars can be read and written.
* Normally, vertex varying vars are implemented as output registers.
* On some hardware, trying to read an output register causes trouble.
* So, rewrite the program to use a temporary register in this case.
*/
void
-_mesa_remove_varying_reads(struct gl_program *prog)
+_mesa_remove_output_reads(struct gl_program *prog, enum register_file type)
{
GLuint i;
GLint outputMap[VERT_RESULT_MAX];
GLuint numVaryingReads = 0;
assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
+ assert(type == PROGRAM_UNIFORM || type == PROGRAM_OUTPUT);
for (i = 0; i < VERT_RESULT_MAX; i++)
outputMap[i] = -1;
@@ -391,7 +393,7 @@ _mesa_remove_varying_reads(struct gl_program *prog)
const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
GLuint j;
for (j = 0; j < numSrc; j++) {
- if (inst->SrcReg[j].File == PROGRAM_VARYING) {
+ if (inst->SrcReg[j].File == type) {
/* replace the read with a temp reg */
const GLuint var = inst->SrcReg[j].Index;
if (outputMap[var] == -1) {
@@ -414,7 +416,7 @@ _mesa_remove_varying_reads(struct gl_program *prog)
const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
GLuint j;
for (j = 0; j < numSrc; j++) {
- if (inst->DstReg.File == PROGRAM_VARYING &&
+ if (inst->DstReg.File == type &&
outputMap[inst->DstReg.Index] >= 0) {
/* change inst to write to the temp reg, instead of the varying */
inst->DstReg.File = PROGRAM_TEMPORARY;
@@ -447,7 +449,7 @@ _mesa_remove_varying_reads(struct gl_program *prog)
if (outputMap[var] >= 0) {
/* MOV VAR[var], TEMP[tmp]; */
inst->Opcode = OPCODE_MOV;
- inst->DstReg.File = PROGRAM_VARYING;
+ inst->DstReg.File = type;
inst->DstReg.Index = var;
inst->SrcReg[0].File = PROGRAM_TEMPORARY;
inst->SrcReg[0].Index = outputMap[var];
diff --git a/src/mesa/shader/programopt.h b/src/mesa/shader/programopt.h
index 47ff2f0c7b..11572e64f5 100644
--- a/src/mesa/shader/programopt.h
+++ b/src/mesa/shader/programopt.h
@@ -40,6 +40,6 @@ extern void
_mesa_count_texture_instructions(struct gl_program *prog);
extern void
-_mesa_remove_varying_reads(struct gl_program *prog);
+_mesa_remove_output_reads(struct gl_program *prog, enum register_file type);
#endif /* PROGRAMOPT_H */
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index f2e8aab8b0..cdea1c5128 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -2212,7 +2212,8 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
printf("Pre-remove output reads:\n");
_mesa_print_program(shader->Programs[0]);
#endif
- _mesa_remove_varying_reads(shader->Programs[0]);
+ _mesa_remove_output_reads(shader->Programs[0], PROGRAM_VARYING);
+ _mesa_remove_output_reads(shader->Programs[0], PROGRAM_OUTPUT);
#if 0
printf("Post-remove output reads:\n");
_mesa_print_program(shader->Programs[0]);