summaryrefslogtreecommitdiffstats
path: root/src/mesa/shader/slang
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2008-08-15 15:00:18 -0600
committerBrian Paul <[email protected]>2008-08-15 15:00:18 -0600
commit2e40e44bf43d968e64d313cbb3b325a9772d5389 (patch)
tree3edd995431443fe67ef1590da4cf2ab2621a02c2 /src/mesa/shader/slang
parent52a6b7e6da8cabf7104c17becb81dea26c44db18 (diff)
mesa: glsl: fix linking of varying vars which are arrays
Diffstat (limited to 'src/mesa/shader/slang')
-rw-r--r--src/mesa/shader/slang/slang_codegen.c6
-rw-r--r--src/mesa/shader/slang/slang_link.c80
2 files changed, 44 insertions, 42 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index db25106d036..f96c6557596 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -3727,6 +3727,8 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
if (dbg) printf("UNIFORM (sz %d) ", totalSize);
}
else if (var->type.qualifier == SLANG_QUAL_VARYING) {
+ const GLint totalSize = array_size(size, var->array_len);
+
/* varyings must be float, vec or mat */
if (!_slang_type_is_float_vec_mat(var->type.specifier.type) &&
var->type.specifier.type != SLANG_SPEC_ARRAY) {
@@ -3744,10 +3746,10 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
if (prog) {
/* user-defined varying */
- GLint varyingLoc = _mesa_add_varying(prog->Varying, varName, size);
+ GLint varyingLoc = _mesa_add_varying(prog->Varying, varName, totalSize);
GLuint swizzle = _slang_var_swizzle(size, 0);
store = _slang_new_ir_storage_swz(PROGRAM_VARYING, varyingLoc,
- size, swizzle);
+ totalSize, swizzle);
}
else {
/* pre-defined varying, like gl_Color or gl_TexCoord */
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index d96380e03f8..e33272eff2a 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -42,6 +42,20 @@
#include "slang_link.h"
+/**
+ * Record a linking error.
+ */
+static void
+link_error(struct gl_shader_program *shProg, const char *msg)
+{
+ if (shProg->InfoLog) {
+ _mesa_free(shProg->InfoLog);
+ }
+ shProg->InfoLog = _mesa_strdup(msg);
+ shProg->LinkStatus = GL_FALSE;
+}
+
+
/**
* Linking varying vars involves rearranging varying vars so that the
@@ -52,7 +66,6 @@ static GLboolean
link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
{
GLuint *map, i, firstVarying, newFile;
- GLbitfield varsWritten, varsRead;
map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint));
if (!map)
@@ -60,14 +73,13 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
for (i = 0; i < prog->Varying->NumParameters; i++) {
/* see if this varying is in the linked varying list */
- const struct gl_program_parameter *var
- = prog->Varying->Parameters + i;
-
+ const struct gl_program_parameter *var = prog->Varying->Parameters + i;
GLint j = _mesa_lookup_parameter_index(shProg->Varying, -1, var->Name);
if (j >= 0) {
/* already in list, check size */
if (var->Size != shProg->Varying->Parameters[j].Size) {
/* error */
+ link_error(shProg, "mismatched varying variable types");
return GL_FALSE;
}
}
@@ -75,9 +87,19 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
/* not already in linked list */
j = _mesa_add_varying(shProg->Varying, var->Name, var->Size);
}
- ASSERT(j >= 0);
- map[i] = j;
+ /* map varying[i] to varying[j].
+ * Note: the loop here takes care of arrays or large (sz>4) vars.
+ */
+ {
+ GLint sz = var->Size;
+ while (sz > 0) {
+ /*printf("Link varying from %d to %d\n", i, j);*/
+ map[i++] = j++;
+ sz -= 4;
+ }
+ i--; /* go back one */
+ }
}
@@ -96,9 +118,6 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
newFile = PROGRAM_INPUT;
}
- /* keep track of which varying vars we read and write */
- varsWritten = varsRead = 0x0;
-
/* OK, now scan the program/shader instructions looking for varying vars,
* replacing the old index with the new index.
*/
@@ -109,30 +128,22 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
if (inst->DstReg.File == PROGRAM_VARYING) {
inst->DstReg.File = newFile;
inst->DstReg.Index = map[ inst->DstReg.Index ] + firstVarying;
- varsWritten |= (1 << inst->DstReg.Index);
}
for (j = 0; j < 3; j++) {
if (inst->SrcReg[j].File == PROGRAM_VARYING) {
inst->SrcReg[j].File = newFile;
inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ] + firstVarying;
- varsRead |= (1 << inst->SrcReg[j].Index);
}
}
}
- if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
- prog->OutputsWritten |= varsWritten;
- /*printf("VERT OUTPUTS: 0x%x \n", varsWritten);*/
- }
- else {
- assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
- prog->InputsRead |= varsRead;
- /*printf("FRAG INPUTS: 0x%x\n", varsRead);*/
- }
-
free(map);
+ /* these will get recomputed before linking is completed */
+ prog->InputsRead = 0x0;
+ prog->OutputsWritten = 0x0;
+
return GL_TRUE;
}
@@ -382,21 +393,6 @@ fragment_program(struct gl_program *prog)
/**
- * Record a linking error.
- */
-static void
-link_error(struct gl_shader_program *shProg, const char *msg)
-{
- if (shProg->InfoLog) {
- _mesa_free(shProg->InfoLog);
- }
- shProg->InfoLog = _mesa_strdup(msg);
- shProg->LinkStatus = GL_FALSE;
-}
-
-
-
-/**
* Shader linker. Currently:
*
* 1. The last attached vertex shader and fragment shader are linked.
@@ -478,10 +474,14 @@ _slang_link(GLcontext *ctx,
}
/* link varying vars */
- if (shProg->VertexProgram)
- link_varying_vars(shProg, &shProg->VertexProgram->Base);
- if (shProg->FragmentProgram)
- link_varying_vars(shProg, &shProg->FragmentProgram->Base);
+ if (shProg->VertexProgram) {
+ if (!link_varying_vars(shProg, &shProg->VertexProgram->Base))
+ return;
+ }
+ if (shProg->FragmentProgram) {
+ if (!link_varying_vars(shProg, &shProg->FragmentProgram->Base))
+ return;
+ }
/* link uniform vars */
if (shProg->VertexProgram)