r300: move some more function to generic
[mesa.git] / src / mesa / shader / slang / slang_compile_variable.c
index 92951b85bbca4e374ee29accdc38d3ae30f5562b..3428b49e1667a8204d5ae1fb51292be83d436a51 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  6.5.3
  *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2005-2007  Brian Paul   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"),
  * \author Michal Krol
  */
 
-#include "imports.h"
+#include "main/imports.h"
 #include "slang_compile.h"
+#include "slang_mem.h"
 
-/* slang_type_specifier_type */
 
 typedef struct
 {
@@ -40,29 +40,37 @@ typedef struct
 } type_specifier_type_name;
 
 static const type_specifier_type_name type_specifier_type_names[] = {
-   {"void", slang_spec_void},
-   {"bool", slang_spec_bool},
-   {"bvec2", slang_spec_bvec2},
-   {"bvec3", slang_spec_bvec3},
-   {"bvec4", slang_spec_bvec4},
-   {"int", slang_spec_int},
-   {"ivec2", slang_spec_ivec2},
-   {"ivec3", slang_spec_ivec3},
-   {"ivec4", slang_spec_ivec4},
-   {"float", slang_spec_float},
-   {"vec2", slang_spec_vec2},
-   {"vec3", slang_spec_vec3},
-   {"vec4", slang_spec_vec4},
-   {"mat2", slang_spec_mat2},
-   {"mat3", slang_spec_mat3},
-   {"mat4", slang_spec_mat4},
-   {"sampler1D", slang_spec_sampler1D},
-   {"sampler2D", slang_spec_sampler2D},
-   {"sampler3D", slang_spec_sampler3D},
-   {"samplerCube", slang_spec_samplerCube},
-   {"sampler1DShadow", slang_spec_sampler1DShadow},
-   {"sampler2DShadow", slang_spec_sampler2DShadow},
-   {NULL, slang_spec_void}
+   {"void", SLANG_SPEC_VOID},
+   {"bool", SLANG_SPEC_BOOL},
+   {"bvec2", SLANG_SPEC_BVEC2},
+   {"bvec3", SLANG_SPEC_BVEC3},
+   {"bvec4", SLANG_SPEC_BVEC4},
+   {"int", SLANG_SPEC_INT},
+   {"ivec2", SLANG_SPEC_IVEC2},
+   {"ivec3", SLANG_SPEC_IVEC3},
+   {"ivec4", SLANG_SPEC_IVEC4},
+   {"float", SLANG_SPEC_FLOAT},
+   {"vec2", SLANG_SPEC_VEC2},
+   {"vec3", SLANG_SPEC_VEC3},
+   {"vec4", SLANG_SPEC_VEC4},
+   {"mat2", SLANG_SPEC_MAT2},
+   {"mat3", SLANG_SPEC_MAT3},
+   {"mat4", SLANG_SPEC_MAT4},
+   {"mat2x3", SLANG_SPEC_MAT23},
+   {"mat3x2", SLANG_SPEC_MAT32},
+   {"mat2x4", SLANG_SPEC_MAT24},
+   {"mat4x2", SLANG_SPEC_MAT42},
+   {"mat3x4", SLANG_SPEC_MAT34},
+   {"mat4x3", SLANG_SPEC_MAT43},
+   {"sampler1D", SLANG_SPEC_SAMPLER1D},
+   {"sampler2D", SLANG_SPEC_SAMPLER2D},
+   {"sampler3D", SLANG_SPEC_SAMPLER3D},
+   {"samplerCube", SLANG_SPEC_SAMPLERCUBE},
+   {"sampler1DShadow", SLANG_SPEC_SAMPLER1DSHADOW},
+   {"sampler2DShadow", SLANG_SPEC_SAMPLER2DSHADOW},
+   {"sampler2DRect", SLANG_SPEC_SAMPLER2DRECT},
+   {"sampler2DRectShadow", SLANG_SPEC_SAMPLER2DRECTSHADOW},
+   {NULL, SLANG_SPEC_VOID}
 };
 
 slang_type_specifier_type
@@ -94,7 +102,7 @@ slang_type_specifier_type_to_string(slang_type_specifier_type type)
 int
 slang_fully_specified_type_construct(slang_fully_specified_type * type)
 {
-   type->qualifier = slang_qual_none;
+   type->qualifier = SLANG_QUAL_NONE;
    slang_type_specifier_ctr(&type->specifier);
    return 1;
 }
@@ -123,10 +131,44 @@ slang_fully_specified_type_copy(slang_fully_specified_type * x,
    return 1;
 }
 
+
+static slang_variable *
+slang_variable_new(void)
+{
+   slang_variable *v = (slang_variable *) _slang_alloc(sizeof(slang_variable));
+   if (v) {
+      if (!slang_variable_construct(v)) {
+         _slang_free(v);
+         v = NULL;
+      }
+   }
+   return v;
+}
+
+
+static void
+slang_variable_delete(slang_variable * var)
+{
+   slang_variable_destruct(var);
+   _slang_free(var);
+}
+
+
 /*
  * slang_variable_scope
  */
 
+slang_variable_scope *
+_slang_variable_scope_new(slang_variable_scope *parent)
+{
+   slang_variable_scope *s;
+   s = (slang_variable_scope *) _slang_alloc(sizeof(slang_variable_scope));
+   if (s)
+      s->outer_scope = parent;
+   return s;
+}
+
+
 GLvoid
 _slang_variable_scope_ctr(slang_variable_scope * self)
 {
@@ -142,9 +184,11 @@ slang_variable_scope_destruct(slang_variable_scope * scope)
 
    if (!scope)
       return;
-   for (i = 0; i < scope->num_variables; i++)
-      slang_variable_destruct(scope->variables + i);
-   slang_alloc_free(scope->variables);
+   for (i = 0; i < scope->num_variables; i++) {
+      if (scope->variables[i])
+         slang_variable_delete(scope->variables[i]);
+   }
+   _slang_free(scope->variables);
    /* do not free scope->outer_scope */
 }
 
@@ -156,21 +200,22 @@ slang_variable_scope_copy(slang_variable_scope * x,
    unsigned int i;
 
    _slang_variable_scope_ctr(&z);
-   z.variables = (slang_variable *)
-      slang_alloc_malloc(y->num_variables * sizeof(slang_variable));
+   z.variables = (slang_variable **)
+      _slang_alloc(y->num_variables * sizeof(slang_variable *));
    if (z.variables == NULL) {
       slang_variable_scope_destruct(&z);
       return 0;
    }
    for (z.num_variables = 0; z.num_variables < y->num_variables;
         z.num_variables++) {
-      if (!slang_variable_construct(&z.variables[z.num_variables])) {
+      z.variables[z.num_variables] = slang_variable_new();
+      if (!z.variables[z.num_variables]) {
          slang_variable_scope_destruct(&z);
          return 0;
       }
    }
    for (i = 0; i < z.num_variables; i++) {
-      if (!slang_variable_copy(&z.variables[i], &y->variables[i])) {
+      if (!slang_variable_copy(z.variables[i], y->variables[i])) {
          slang_variable_scope_destruct(&z);
          return 0;
       }
@@ -181,6 +226,33 @@ slang_variable_scope_copy(slang_variable_scope * x,
    return 1;
 }
 
+
+/**
+ * Grow the variable list by one.
+ * \return  pointer to space for the new variable (will be initialized)
+ */
+slang_variable *
+slang_variable_scope_grow(slang_variable_scope *scope)
+{
+   const int n = scope->num_variables;
+   scope->variables = (slang_variable **)
+         _slang_realloc(scope->variables,
+                        n * sizeof(slang_variable *),
+                        (n + 1) * sizeof(slang_variable *));
+   if (!scope->variables)
+      return NULL;
+
+   scope->num_variables++;
+
+   scope->variables[n] = slang_variable_new();
+   if (!scope->variables[n])
+      return NULL;
+
+   return scope->variables[n];
+}
+
+
+
 /* slang_variable */
 
 int
@@ -192,22 +264,30 @@ slang_variable_construct(slang_variable * var)
    var->array_len = 0;
    var->initializer = NULL;
    var->address = ~0;
-   var->address2 = 0;
    var->size = 0;
-   var->global = GL_FALSE;
+   var->isTemp = GL_FALSE;
+   var->aux = NULL;
+   var->declared = 0;
    return 1;
 }
 
+
 void
 slang_variable_destruct(slang_variable * var)
 {
    slang_fully_specified_type_destruct(&var->type);
    if (var->initializer != NULL) {
       slang_operation_destruct(var->initializer);
-      slang_alloc_free(var->initializer);
+      _slang_free(var->initializer);
+   }
+#if 0
+   if (var->aux) {
+      _mesa_free(var->aux);
    }
+#endif
 }
 
+
 int
 slang_variable_copy(slang_variable * x, const slang_variable * y)
 {
@@ -222,14 +302,14 @@ slang_variable_copy(slang_variable * x, const slang_variable * y)
    z.a_name = y->a_name;
    z.array_len = y->array_len;
    if (y->initializer != NULL) {
-      z.initializer =
-         (slang_operation *) slang_alloc_malloc(sizeof(slang_operation));
+      z.initializer
+         = (slang_operation *) _slang_alloc(sizeof(slang_operation));
       if (z.initializer == NULL) {
          slang_variable_destruct(&z);
          return 0;
       }
       if (!slang_operation_construct(z.initializer)) {
-         slang_alloc_free(z.initializer);
+         _slang_free(z.initializer);
          slang_variable_destruct(&z);
          return 0;
       }
@@ -240,143 +320,29 @@ slang_variable_copy(slang_variable * x, const slang_variable * y)
    }
    z.address = y->address;
    z.size = y->size;
-   z.global = y->global;
    slang_variable_destruct(x);
    *x = z;
    return 1;
 }
 
+
+/**
+ * Search for named variable in given scope.
+ * \param all  if true, search parent scopes too.
+ */
 slang_variable *
 _slang_locate_variable(const slang_variable_scope * scope,
                        const slang_atom a_name, GLboolean all)
 {
-   GLuint i;
-
-   for (i = 0; i < scope->num_variables; i++)
-      if (a_name == scope->variables[i].a_name)
-         return &scope->variables[i];
-   if (all && scope->outer_scope != NULL)
-      return _slang_locate_variable(scope->outer_scope, a_name, 1);
-   return NULL;
-}
-
-/*
- * _slang_build_export_data_table()
- */
-
-static GLenum
-gl_type_from_specifier(const slang_type_specifier * type)
-{
-   switch (type->type) {
-   case slang_spec_bool:
-      return GL_BOOL_ARB;
-   case slang_spec_bvec2:
-      return GL_BOOL_VEC2_ARB;
-   case slang_spec_bvec3:
-      return GL_BOOL_VEC3_ARB;
-   case slang_spec_bvec4:
-      return GL_BOOL_VEC4_ARB;
-   case slang_spec_int:
-      return GL_INT;
-   case slang_spec_ivec2:
-      return GL_INT_VEC2_ARB;
-   case slang_spec_ivec3:
-      return GL_INT_VEC3_ARB;
-   case slang_spec_ivec4:
-      return GL_INT_VEC4_ARB;
-   case slang_spec_float:
-      return GL_FLOAT;
-   case slang_spec_vec2:
-      return GL_FLOAT_VEC2_ARB;
-   case slang_spec_vec3:
-      return GL_FLOAT_VEC3_ARB;
-   case slang_spec_vec4:
-      return GL_FLOAT_VEC4_ARB;
-   case slang_spec_mat2:
-      return GL_FLOAT_MAT2_ARB;
-   case slang_spec_mat3:
-      return GL_FLOAT_MAT3_ARB;
-   case slang_spec_mat4:
-      return GL_FLOAT_MAT4_ARB;
-   case slang_spec_sampler1D:
-      return GL_SAMPLER_1D_ARB;
-   case slang_spec_sampler2D:
-      return GL_SAMPLER_2D_ARB;
-   case slang_spec_sampler3D:
-      return GL_SAMPLER_3D_ARB;
-   case slang_spec_samplerCube:
-      return GL_SAMPLER_CUBE_ARB;
-   case slang_spec_sampler1DShadow:
-      return GL_SAMPLER_1D_SHADOW_ARB;
-   case slang_spec_sampler2DShadow:
-      return GL_SAMPLER_2D_SHADOW_ARB;
-   case slang_spec_array:
-      return gl_type_from_specifier(type->_array);
-   default:
-      return GL_FLOAT;
-   }
-}
-
-static GLboolean
-build_quant(slang_export_data_quant * q, const slang_variable * var)
-{
-   const slang_type_specifier *spec = &var->type.specifier;
-
-   q->name = var->a_name;
-   q->size = var->size;
-   if (spec->type == slang_spec_array) {
-      q->array_len = var->array_len;
-      q->size /= var->array_len;
-      spec = spec->_array;
-   }
-   if (spec->type == slang_spec_struct) {
+   while (scope) {
       GLuint i;
-
-      q->u.field_count = spec->_struct->fields->num_variables;
-      q->structure = (slang_export_data_quant *)
-         slang_alloc_malloc(q->u.field_count
-                            * sizeof(slang_export_data_quant));
-      if (q->structure == NULL)
-         return GL_FALSE;
-
-      for (i = 0; i < q->u.field_count; i++)
-         slang_export_data_quant_ctr(&q->structure[i]);
-      for (i = 0; i < q->u.field_count; i++) {
-         if (!build_quant(&q->structure[i],
-                          &spec->_struct->fields->variables[i]))
-            return GL_FALSE;
-      }
-   }
-   else
-      q->u.basic_type = gl_type_from_specifier(spec);
-   return GL_TRUE;
-}
-
-GLboolean
-_slang_build_export_data_table(slang_export_data_table * tbl,
-                               slang_variable_scope * vars)
-{
-   GLuint i;
-
-   for (i = 0; i < vars->num_variables; i++) {
-      const slang_variable *var = &vars->variables[i];
-      slang_export_data_entry *e;
-
-      e = slang_export_data_table_add(tbl);
-      if (e == NULL)
-         return GL_FALSE;
-      if (!build_quant(&e->quant, var))
-         return GL_FALSE;
-      if (var->type.qualifier == slang_qual_uniform)
-         e->access = slang_exp_uniform;
-      else if (var->type.qualifier == slang_qual_attribute)
-         e->access = slang_exp_attribute;
+      for (i = 0; i < scope->num_variables; i++)
+         if (a_name == scope->variables[i]->a_name)
+            return scope->variables[i];
+      if (all)
+         scope = scope->outer_scope;
       else
-         e->access = slang_exp_varying;
-      e->address = var->address;
+         scope = NULL;
    }
-
-   if (vars->outer_scope != NULL)
-      return _slang_build_export_data_table(tbl, vars->outer_scope);
-   return GL_TRUE;
+   return NULL;
 }