glsl: support sampler arrays.
authorAlan Hourihane <alanh@vmware.com>
Tue, 13 Jan 2009 23:54:46 +0000 (23:54 +0000)
committerAlan Hourihane <alanh@vmware.com>
Wed, 14 Jan 2009 00:12:33 +0000 (00:12 +0000)
src/mesa/shader/slang/slang_codegen.c
src/mesa/shader/slang/slang_emit.c
src/mesa/shader/slang/slang_link.c

index f5c5cbdd484c6a1dfdda6d66cdeefcbca3972c30..20946650293b8c248349ad58a865ac36f5d8d053 100644 (file)
@@ -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 ");
    }
index d3b4e64b78dcd489f43e502c9db904f22bab360a..08b7d519a57a77d94efb29dffa2de52b5d769da3 100644 (file)
@@ -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 */
index 26f5d61e04836e8944623a78632cea78c2c1769a..05a3e2dee07aaca2a095e08c5b470e99615b0969 100644 (file)
@@ -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;