Mesa (master): mesa: fix another "out of samplers" problem

Brian Paul brianp at kemper.freedesktop.org
Fri Jan 2 19:28:51 UTC 2009


Module: Mesa
Branch: master
Commit: 1fad6ccb756ae33ca3115f59c99ca8abbeb0321e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1fad6ccb756ae33ca3115f59c99ca8abbeb0321e

Author: Brian Paul <brianp at vmware.com>
Date:   Fri Jan  2 12:26:15 2009 -0700

mesa: fix another "out of samplers" problem

Now only the samplers that are actually used by texture() functions are
saved in the uniform variable list.  Before, we could run out of samplers
if too many were declared while only some of them were actually used.

---

 src/mesa/shader/prog_parameter.c   |    3 +-
 src/mesa/shader/slang/slang_emit.c |    8 ++++-
 src/mesa/shader/slang/slang_link.c |   57 ++++++++++++++++++++++++++----------
 3 files changed, 50 insertions(+), 18 deletions(-)

diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
index c0602ad..dc48e84 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 500112b..b7a3cfb 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 b49fd0e..b2fd955 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);
+         }
       }
    }
 




More information about the mesa-commit mailing list