Mesa (master): glsl: support sampler arrays.

Alan Hourihane alanh at kemper.freedesktop.org
Wed Jan 14 00:13:08 UTC 2009


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

Author: Alan Hourihane <alanh at vmware.com>
Date:   Tue Jan 13 23:54:46 2009 +0000

glsl: support sampler arrays.

---

 src/mesa/shader/slang/slang_codegen.c |   33 +++++++++++++++++++++++++++++----
 src/mesa/shader/slang/slang_emit.c    |   17 ++++++++++++++---
 src/mesa/shader/slang/slang_link.c    |   10 ++++++----
 3 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index f5c5cbd..2094665 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -4261,10 +4261,14 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
    slang_ir_storage *store = NULL;
    int dbg = 0;
    const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
-   const GLint texIndex = sampler_to_texture_index(var->type.specifier.type);
    const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
    const GLint arrayLen = _slang_array_length(var);
    const GLint totalSize = _slang_array_size(size, arrayLen);
+   GLint texIndex = sampler_to_texture_index(var->type.specifier.type);
+
+   /* check for sampler2D arrays */
+   if (texIndex == -1 && var->type.specifier._array)
+      texIndex = sampler_to_texture_index(var->type.specifier._array->type);
 
    if (texIndex != -1) {
       /* This is a texture sampler variable...
@@ -4278,15 +4282,36 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
       }
 #if FEATURE_es2_glsl /* XXX should use FEATURE_texture_rect */
       /* disallow rect samplers */
-      if (var->type.specifier.type == SLANG_SPEC_SAMPLER2DRECT ||
-          var->type.specifier.type == SLANG_SPEC_SAMPLER2DRECTSHADOW) {
+      if ((var->type.specifier._array && 
+           (var->type.specifier._array->type == SLANG_SPEC_SAMPLER2DRECT ||
+            var->type.specifier._array->type == SLANG_SPEC_SAMPLER2DRECTSHADOW)) ||
+          (var->type.specifier.type == SLANG_SPEC_SAMPLER2DRECT ||
+           var->type.specifier.type == SLANG_SPEC_SAMPLER2DRECTSHADOW)) {
          slang_info_log_error(A->log, "invalid sampler type for '%s'", varName);
          return GL_FALSE;
       }
 #endif
       {
+         const GLuint swizzle = _slang_var_swizzle(totalSize, 0);
          GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype);
-         store = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, texIndex);
+         store = _slang_new_ir_storage_swz(PROGRAM_SAMPLER, sampNum,
+                                                 totalSize, swizzle);
+
+         /* If we have a sampler array, then we need to allocate the 
+	  * additional samplers to ensure we don't allocate them elsewhere.
+	  * We can't directly use _mesa_add_sampler() as that checks the
+	  * varName and gets a match, so we call _mesa_add_parameter()
+	  * directly and use the last sampler number for the call above.
+	  */
+	 if (arrayLen > 0) {
+	    GLint a = arrayLen - 1;
+	    GLint i;
+	    for (i = 0; i < a; i++) {
+               GLfloat value = (GLfloat)(i + sampNum + 1);
+               (void) _mesa_add_parameter(prog->Parameters, PROGRAM_SAMPLER,
+                                 varName, 1, datatype, &value, NULL, 0x0);
+	    }
+	 }
       }
       if (dbg) printf("SAMPLER ");
    }
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index d3b4e64..08b7d51 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -1271,6 +1271,20 @@ emit_tex(slang_emit_info *emitInfo, slang_ir_node *n)
       opcode = OPCODE_TXP;
    }
 
+   if (n->Children[0]->Opcode == IR_ELEMENT) {
+      /* array is the sampler (a uniform which'll indicate the texture unit) */
+      assert(n->Children[0]->Children[0]->Store);
+      assert(n->Children[0]->Children[0]->Store->File == PROGRAM_SAMPLER);
+
+      emit(emitInfo, n->Children[0]);
+
+      n->Children[0]->Var = n->Children[0]->Children[0]->Var;
+   } else {
+      /* this is the sampler (a uniform which'll indicate the texture unit) */
+      assert(n->Children[0]->Store);
+      assert(n->Children[0]->Store->File == PROGRAM_SAMPLER);
+   }
+
    /* emit code for the texcoord operand */
    (void) emit(emitInfo, n->Children[1]);
 
@@ -1286,9 +1300,6 @@ emit_tex(slang_emit_info *emitInfo, slang_ir_node *n)
                            NULL,
                            NULL);
 
-   /* 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 */
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 26f5d61..05a3e2d 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -282,12 +282,14 @@ link_uniform_vars(GLcontext *ctx,
    for (i = 0; i < prog->NumInstructions; i++) {
       struct prog_instruction *inst = prog->Instructions + i;
       if (_mesa_is_tex_instruction(inst->Opcode)) {
-         /*
+         const GLint oldSampNum = inst->TexSrcUnit;
+
+#if 0
          printf("====== remap sampler from %d to %d\n",
-                inst->Sampler, map[ inst->Sampler ]);
-         */
+                inst->TexSrcUnit, samplerMap[ inst->TexSrcUnit ]);
+#endif
+
          /* here, texUnit is really samplerUnit */
-         const GLint oldSampNum = inst->TexSrcUnit;
          if (oldSampNum < Elements(samplerMap)) {
             const GLuint newSampNum = samplerMap[oldSampNum];
             inst->TexSrcUnit = newSampNum;




More information about the mesa-commit mailing list