diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2008-12-11 19:28:22 -0700 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2008-12-11 19:28:22 -0700 | 
| commit | 2760bca1e13e62943affd762ed560bc30fbcc27a (patch) | |
| tree | b40bd749911e36324b0f3cb51e73f41d44885577 /src/mesa/shader | |
| parent | 05ed9f7fe934249eaa5a16123b5b5f7f62b0ad26 (diff) | |
mesa: move variable initializer IR generation into _slang_gen_var_decl()
More code consolidation coming...
Diffstat (limited to 'src/mesa/shader')
| -rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 172 | 
1 files changed, 93 insertions, 79 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 99973243cc..07928c68a0 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -2477,70 +2477,125 @@ _slang_gen_temporary(GLint size)  /**   * Generate IR node for allocating/declaring a variable. + * \param initializer  Optional initializer expression for the variable.   */  static slang_ir_node * -_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var) +_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var, +                    slang_operation *initializer)  { -   slang_ir_node *n; +   slang_ir_node *varDecl, *n; +   slang_ir_storage *store;     /*assert(!var->declared);*/     var->declared = GL_TRUE; -   n = new_node0(IR_VAR_DECL); -   if (!n) +   varDecl = new_node0(IR_VAR_DECL); +   if (!varDecl)        return NULL; -   _slang_attach_storage(n, var); +   _slang_attach_storage(varDecl, var);     assert(var->store); -   assert(n->Store == var->store); -   assert(n->Store); -   assert(n->Store->Index < 0); +   assert(varDecl->Store == var->store); +   assert(varDecl->Store); +   assert(varDecl->Store->Index < 0); +   store = var->store; + +   assert(store == varDecl->Store); +   /* determine GPU storage file */ +   /* XXX if the variable is const, use PROGRAM_CONSTANT */     if (is_sampler_type(&var->type)) { -      n->Store->File = PROGRAM_SAMPLER; +      store->File = PROGRAM_SAMPLER;     }     else { -      n->Store->File = PROGRAM_TEMPORARY; +      store->File = PROGRAM_TEMPORARY;     } -   n->Store->Size = _slang_sizeof_type_specifier(&n->Var->type.specifier); +   store->Size = _slang_sizeof_type_specifier(&varDecl->Var->type.specifier); -   if (n->Store->Size <= 0) { +   if (store->Size <= 0) {        slang_info_log_error(A->log, "invalid declaration for '%s'",                             (char*) var->a_name);        return NULL;     } +  #if 0     printf("%s var %p %s  store=%p index=%d size=%d\n",            __FUNCTION__, (void *) var, (char *) var->a_name, -          (void *) n->Store, n->Store->Index, n->Store->Size); +          (void *) store, store->Index, store->Size);  #endif     if (var->array_len > 0) {        /* this is an array */        /* round up the element size to a multiple of 4 */ -      GLint sz = (n->Store->Size + 3) & ~3; +      GLint sz = (store->Size + 3) & ~3;        /* total size = element size * array length */        sz *= var->array_len; -      n->Store->Size = sz; +      store->Size = sz;     }     /* setup default swizzle for storing the variable */     /* XXX this may not be needed anymore - remove & test */ -   switch (n->Store->Size) { +   switch (store->Size) {     case 2: -      n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, -                                        SWIZZLE_NIL, SWIZZLE_NIL); +      store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, +                                     SWIZZLE_NIL, SWIZZLE_NIL);        break;     case 3: -      n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, -                                        SWIZZLE_Z, SWIZZLE_NIL); +      store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, +                                     SWIZZLE_Z, SWIZZLE_NIL);        break;     default:        /* Note that float-sized vars may be allocated in any x/y/z/w         * slot, but that won't be determined until code emit time.         */ -      n->Store->Swizzle = SWIZZLE_NOOP; +      store->Swizzle = SWIZZLE_NOOP; +   } + +   /* if there's an initializer, generate IR for the expression */ +   if (initializer) { +      const char *varName = (const char *) var->a_name; +      slang_ir_node *varRef, *init; + +      varRef = new_var(A, var); +      if (!varRef) { +         slang_info_log_error(A->log, "undefined variable '%s'", varName); +         return NULL; +      } + +      if (var->type.qualifier == SLANG_QUAL_CONST) { +         /* if the variable is const, the initializer must be a const +          * expression as well. +          */ +#if 0 +         if (!_slang_is_constant_expr(initializer)) { +            slang_info_log_error(A->log, +                                 "initializer for %s not constant", varName); +            return NULL; +         } +#endif +      } + +      _slang_simplify(initializer, &A->space, A->atoms);  + +      init = _slang_gen_operation(A, initializer); +      if (!init) +         return NULL; + +      /*assert(init->Store);*/ + +      /* XXX remove this when type checking is added above */ +      if (init->Store && varRef->Store->Size != init->Store->Size) { +         slang_info_log_error(A->log, "invalid assignment (wrong types)"); +         return NULL; +      } + +      n = new_node2(IR_COPY, varRef, init); +      n = new_seq(varDecl, n); +   } +   else { +      /* no initializer */ +      n = varDecl;     }     return n; @@ -2835,20 +2890,20 @@ _slang_assignment_compatible(slang_assemble_ctx *A,  /** - * Generate IR tree for a variable declaration. + * Generate IR tree for a local variable declaration.   */  static slang_ir_node *  _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)  { -   slang_ir_node *n; -   slang_ir_node *varDecl; -   slang_variable *var;     const char *varName = (char *) oper->a_id; +   slang_variable *var; +   slang_ir_node *varDecl;     slang_operation *initializer;     assert(oper->type == SLANG_OPER_VARIABLE_DECL);     assert(oper->num_children <= 1); +   /* lookup the variable by name */     var = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE);     if (!var)        return NULL;  /* "shouldn't happen" */ @@ -2870,10 +2925,6 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)     }  #endif -   varDecl = _slang_gen_var_decl(A, var); -   if (!varDecl) -      return NULL; -     /* check if the var has an initializer */     if (oper->num_children > 0) {        assert(oper->num_children == 1); @@ -2886,64 +2937,27 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)        initializer = NULL;     } -   if (var->type.qualifier == SLANG_QUAL_CONST && !initializer) { -      slang_info_log_error(A->log, -                           "const-qualified variable '%s' requires initializer", -                           varName); -      return NULL; -   } - -     if (initializer) { -      slang_ir_node *varRef, *init; - -      /* type check/compare var and initializer */ +      /* check/compare var type and initializer type */        if (!_slang_assignment_compatible(A, oper, initializer)) {           slang_info_log_error(A->log, "incompatible types in assignment");           return NULL;        }          +   } -      varRef = new_var(A, var); -      if (!varRef) { -         slang_info_log_error(A->log, "undefined variable '%s'", varName); -         return NULL; -      } - -      if (var->type.qualifier == SLANG_QUAL_CONST) { -         /* if the variable is const, the initializer must be a const -          * expression as well. -          */ -#if 0 -         if (!_slang_is_constant_expr(initializer)) { -            slang_info_log_error(A->log, -                                 "initializer for %s not constant", varName); -            return NULL; -         } -#endif -      } - -      _slang_simplify(initializer, &A->space, A->atoms);  - -      init = _slang_gen_operation(A, initializer); -      if (!init) -         return NULL; - -      /*assert(init->Store);*/ - -      /* XXX remove this when type checking is added above */ -      if (init->Store && varRef->Store->Size != init->Store->Size) { -         slang_info_log_error(A->log, "invalid assignment (wrong types)"); -         return NULL; -      } +   /* Generate IR node */ +   varDecl = _slang_gen_var_decl(A, var, initializer); +   if (!varDecl) +      return NULL; -      n = new_node2(IR_COPY, varRef, init); -      n = new_seq(varDecl, n); -   } -   else { -      n = varDecl; +   if (var->type.qualifier == SLANG_QUAL_CONST && !initializer) { +      slang_info_log_error(A->log, +                           "const-qualified variable '%s' requires initializer", +                           varName); +      return NULL;     } -   return n; +   return varDecl;  } @@ -3927,7 +3941,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,        slang_ir_node *n;        /* IR node to declare the variable */ -      n = _slang_gen_var_decl(A, var); +      n = _slang_gen_var_decl(A, var, NULL);        /* IR code for the var's initializer, if present */        if (var->initializer) {  | 
