summaryrefslogtreecommitdiff
path: root/src/mesa/shader/slang/slang_link.c
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2008-08-16 09:30:14 -0600
committerBrian Paul <brian.paul@tungstengraphics.com>2008-08-16 09:30:14 -0600
commit1f4997c2aaf424c8a12cc6fdb1dd994f66074a1d (patch)
treede14cfe88863d678bc618b54a7569f831fd7f590 /src/mesa/shader/slang/slang_link.c
parent1b39b92e6d7d3a7e6c39b985ffff32a79a510333 (diff)
mesa: import latest GLSL code from gallium-0.1 branch
Diffstat (limited to 'src/mesa/shader/slang/slang_link.c')
-rw-r--r--src/mesa/shader/slang/slang_link.c100
1 files changed, 53 insertions, 47 deletions
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index c0be6fd692..e33272eff2 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;
}
@@ -296,7 +307,7 @@ _slang_count_temporaries(struct gl_program *prog)
maxIndex = inst->SrcReg[j].Index;
}
if (inst->DstReg.File == PROGRAM_TEMPORARY) {
- if (maxIndex < inst->DstReg.Index)
+ if (maxIndex < (GLint) inst->DstReg.Index)
maxIndex = inst->DstReg.Index;
}
}
@@ -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.
@@ -445,6 +441,18 @@ _slang_link(GLcontext *ctx,
_mesa_problem(ctx, "unexpected shader target in slang_link()");
}
+#if FEATURE_es2_glsl
+ /* must have both a vertex and fragment program for ES2 */
+ if (!vertProg) {
+ link_error(shProg, "missing vertex shader\n");
+ return;
+ }
+ if (!fragProg) {
+ link_error(shProg, "missing fragment shader\n");
+ return;
+ }
+#endif
+
/*
* Make copies of the vertex/fragment programs now since we'll be
* changing src/dst registers after merging the uniforms and varying vars.
@@ -466,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)
@@ -517,12 +529,6 @@ _slang_link(GLcontext *ctx,
}
}
- /* Check that the vertex program doesn't use too many sampler units */
- if (shProg->VertexProgram &&
- _mesa_bitcount(shProg->VertexProgram->Base.SamplersUsed) > ctx->Const.MaxVertexTextureImageUnits) {
- link_error(shProg, "Vertex program uses too many samplers.\n");
- return;
- }
if (fragProg && shProg->FragmentProgram) {
/* notify driver that a new fragment program has been compiled/linked */