mesa: move _slang_locate_function() to different file
[mesa.git] / src / mesa / shader / slang / slang_typeinfo.c
index fef5575631b7379f11b4562ed2ab5008499b6f25..430fc10b672fa8899c09567c5935a177c5b3d9a5 100644 (file)
  * \author Michal Krol
  */
 
-#include "imports.h"
+#include "main/imports.h"
+#include "shader/prog_instruction.h"
 #include "slang_typeinfo.h"
 #include "slang_compile.h"
 #include "slang_log.h"
-#include "prog_instruction.h"
+#include "slang_mem.h"
 
 
 /**
@@ -178,14 +179,29 @@ slang_type_specifier_dtr(slang_type_specifier * self)
 {
    if (self->_struct != NULL) {
       slang_struct_destruct(self->_struct);
-      slang_alloc_free(self->_struct);
+      _slang_free(self->_struct);
    }
    if (self->_array != NULL) {
       slang_type_specifier_dtr(self->_array);
-      slang_alloc_free(self->_array);
+      _slang_free(self->_array);
    }
 }
 
+slang_type_specifier *
+slang_type_specifier_new(slang_type_specifier_type type,
+                         struct slang_struct_ *_struct,
+                         struct slang_type_specifier_ *_array)
+{
+   slang_type_specifier *spec =
+      (slang_type_specifier *) _mesa_malloc(sizeof(slang_type_specifier));
+   if (spec) {
+      spec->type = type;
+      spec->_struct = _struct;
+      spec->_array = _array;
+   }
+   return spec;
+}
+
 GLboolean
 slang_type_specifier_copy(slang_type_specifier * x,
                           const slang_type_specifier * y)
@@ -195,13 +211,13 @@ slang_type_specifier_copy(slang_type_specifier * x,
    slang_type_specifier_ctr(&z);
    z.type = y->type;
    if (z.type == SLANG_SPEC_STRUCT) {
-      z._struct = (slang_struct *) slang_alloc_malloc(sizeof(slang_struct));
+      z._struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));
       if (z._struct == NULL) {
          slang_type_specifier_dtr(&z);
          return GL_FALSE;
       }
       if (!slang_struct_construct(z._struct)) {
-         slang_alloc_free(z._struct);
+         _slang_free(z._struct);
          slang_type_specifier_dtr(&z);
          return GL_FALSE;
       }
@@ -211,9 +227,8 @@ slang_type_specifier_copy(slang_type_specifier * x,
       }
    }
    else if (z.type == SLANG_SPEC_ARRAY) {
-      z._array =
-         (slang_type_specifier *)
-         slang_alloc_malloc(sizeof(slang_type_specifier));
+      z._array = (slang_type_specifier *)
+         _slang_alloc(sizeof(slang_type_specifier));
       if (z._array == NULL) {
          slang_type_specifier_dtr(&z);
          return GL_FALSE;
@@ -250,7 +265,7 @@ slang_type_specifier_equal(const slang_type_specifier * x,
 /**
  * As above, but allow float/int casting.
  */
-static GLboolean
+GLboolean
 slang_type_specifier_compatible(const slang_type_specifier * x,
                                 const slang_type_specifier * y)
 {
@@ -273,6 +288,7 @@ slang_type_specifier_compatible(const slang_type_specifier * x,
 GLboolean
 slang_typeinfo_construct(slang_typeinfo * ti)
 {
+   _mesa_bzero(ti, sizeof(*ti));
    slang_type_specifier_ctr(&ti->spec);
    ti->array_len = 0;
    return GL_TRUE;
@@ -304,10 +320,16 @@ _slang_typeof_function(slang_atom a_name,
                        slang_function **funFound,
                        slang_atom_pool *atoms, slang_info_log *log)
 {
+   GLboolean error;
+
    *funFound = _slang_locate_function(space->funcs, a_name, params,
-                                      num_params, space, atoms, log);
+                                      num_params, space, atoms, log, &error);
+   if (error)
+      return GL_FALSE;
+
    if (!*funFound)
       return GL_TRUE;  /* yes, not false */
+
    return slang_type_specifier_copy(spec, &(*funFound)->header.type.specifier);
 }
 
@@ -385,7 +407,6 @@ _slang_typeof_operation_(slang_operation * op,
    switch (op->type) {
    case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
    case SLANG_OPER_BLOCK_NEW_SCOPE:
-   case SLANG_OPER_VARIABLE_DECL:
    case SLANG_OPER_ASM:
    case SLANG_OPER_BREAK:
    case SLANG_OPER_CONTINUE:
@@ -470,6 +491,7 @@ _slang_typeof_operation_(slang_operation * op,
       }
       break;
    case SLANG_OPER_IDENTIFIER:
+   case SLANG_OPER_VARIABLE_DECL:
       {
          slang_variable *var;
          var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE);
@@ -576,7 +598,18 @@ _slang_typeof_operation_(slang_operation * op,
       }
       break;
    case SLANG_OPER_CALL:
-      if (op->fun) {
+      if (op->array_constructor) {
+         /* build array typeinfo */
+         ti->spec.type = SLANG_SPEC_ARRAY;
+         ti->spec._array = (slang_type_specifier *)
+            _slang_alloc(sizeof(slang_type_specifier));
+         slang_type_specifier_ctr(ti->spec._array);
+
+         ti->spec._array->type =
+            slang_type_specifier_type_from_string((char *) op->a_id);
+         ti->array_len = op->num_children;
+      }
+      else if (op->fun) {
          /* we've resolved this call before */
          slang_type_specifier_copy(&ti->spec, &op->fun->header.type.specifier);
       }
@@ -596,11 +629,11 @@ _slang_typeof_operation_(slang_operation * op,
                /* struct initializer */
                ti->spec.type = SLANG_SPEC_STRUCT;
                ti->spec._struct =
-                  (slang_struct *) slang_alloc_malloc(sizeof(slang_struct));
+                  (slang_struct *) _slang_alloc(sizeof(slang_struct));
                if (ti->spec._struct == NULL)
                   return GL_FALSE;
                if (!slang_struct_construct(ti->spec._struct)) {
-                  slang_alloc_free(ti->spec._struct);
+                  _slang_free(ti->spec._struct);
                   ti->spec._struct = NULL;
                   return GL_FALSE;
                }
@@ -623,6 +656,12 @@ _slang_typeof_operation_(slang_operation * op,
          }
       }
       break;
+   case SLANG_OPER_METHOD:
+      /* at this time, GLSL 1.20 only has one method: array.length()
+       * which returns an integer.
+       */
+      ti->spec.type = SLANG_SPEC_INT;
+      break;
    case SLANG_OPER_FIELD:
       {
          slang_typeinfo _ti;
@@ -748,62 +787,6 @@ _slang_typeof_operation_(slang_operation * op,
 }
 
 
-/**
- * Lookup a function according to name and parameter count/types.
- */
-slang_function *
-_slang_locate_function(const slang_function_scope * funcs, slang_atom a_name,
-                       slang_operation * args, GLuint num_args,
-                       const slang_name_space * space, slang_atom_pool * atoms,
-                       slang_info_log *log)
-{
-   GLuint i;
-
-   for (i = 0; i < funcs->num_functions; i++) {
-      slang_function *f = &funcs->functions[i];
-      const GLuint haveRetValue = _slang_function_has_return_value(f);
-      GLuint j;
-
-      if (a_name != f->header.a_name)
-         continue;
-      if (f->param_count - haveRetValue != num_args)
-         continue;
-
-      /* compare parameter / argument types */
-      for (j = 0; j < num_args; j++) {
-         slang_typeinfo ti;
-
-         if (!slang_typeinfo_construct(&ti))
-            return NULL;
-         if (!_slang_typeof_operation_(&args[j], space, &ti, atoms, log)) {
-            slang_typeinfo_destruct(&ti);
-            return NULL;
-         }
-         if (!slang_type_specifier_compatible(&ti.spec,
-             &f->parameters->variables[j]->type.specifier)) {
-            slang_typeinfo_destruct(&ti);
-            break;
-         }
-         slang_typeinfo_destruct(&ti);
-
-         /* "out" and "inout" formal parameter requires the actual
-          * parameter to be l-value.
-          */
-         if (!ti.can_be_referenced &&
-             (f->parameters->variables[j]->type.qualifier == SLANG_QUAL_OUT ||
-              f->parameters->variables[j]->type.qualifier == SLANG_QUAL_INOUT))
-            break;
-      }
-      if (j == num_args)
-         return f;
-   }
-   if (funcs->outer_scope != NULL)
-      return _slang_locate_function(funcs->outer_scope, a_name, args,
-                                    num_args, space, atoms, log);
-   return NULL;
-}
-
-
 /**
  * Determine if a type is a matrix.
  * \return GL_TRUE if is a matrix, GL_FALSE otherwise.
@@ -815,6 +798,12 @@ _slang_type_is_matrix(slang_type_specifier_type ty)
    case SLANG_SPEC_MAT2:
    case SLANG_SPEC_MAT3:
    case SLANG_SPEC_MAT4:
+   case SLANG_SPEC_MAT23:
+   case SLANG_SPEC_MAT32:
+   case SLANG_SPEC_MAT24:
+   case SLANG_SPEC_MAT42:
+   case SLANG_SPEC_MAT34:
+   case SLANG_SPEC_MAT43:
       return GL_TRUE;
    default:
       return GL_FALSE;
@@ -847,7 +836,36 @@ _slang_type_is_vector(slang_type_specifier_type ty)
 
 
 /**
- * Given a vector type, return the type of the vector's elements
+ * Determine if a type is a float, float vector or float matrix.
+ * \return GL_TRUE if so, GL_FALSE otherwise
+ */
+GLboolean
+_slang_type_is_float_vec_mat(slang_type_specifier_type ty)
+{
+   switch (ty) {
+   case SLANG_SPEC_FLOAT:
+   case SLANG_SPEC_VEC2:
+   case SLANG_SPEC_VEC3:
+   case SLANG_SPEC_VEC4:
+   case SLANG_SPEC_MAT2:
+   case SLANG_SPEC_MAT3:
+   case SLANG_SPEC_MAT4:
+   case SLANG_SPEC_MAT23:
+   case SLANG_SPEC_MAT32:
+   case SLANG_SPEC_MAT24:
+   case SLANG_SPEC_MAT42:
+   case SLANG_SPEC_MAT34:
+   case SLANG_SPEC_MAT43:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Given a vector type, return the type of the vector's elements.
+ * For a matrix, return the type of the columns.
  */
 slang_type_specifier_type
 _slang_type_base(slang_type_specifier_type ty)
@@ -874,6 +892,18 @@ _slang_type_base(slang_type_specifier_type ty)
       return SLANG_SPEC_VEC3;
    case SLANG_SPEC_MAT4:
       return SLANG_SPEC_VEC4;
+   case SLANG_SPEC_MAT23:
+      return SLANG_SPEC_VEC3;
+   case SLANG_SPEC_MAT32:
+      return SLANG_SPEC_VEC2;
+   case SLANG_SPEC_MAT24:
+      return SLANG_SPEC_VEC4;
+   case SLANG_SPEC_MAT42:
+      return SLANG_SPEC_VEC2;
+   case SLANG_SPEC_MAT34:
+      return SLANG_SPEC_VEC4;
+   case SLANG_SPEC_MAT43:
+      return SLANG_SPEC_VEC3;
    default:
       return SLANG_SPEC_VOID;
    }
@@ -881,7 +911,8 @@ _slang_type_base(slang_type_specifier_type ty)
 
 
 /**
- * Return the dimensionality of a vector or matrix type.
+ * Return the dimensionality of a vector, or for a matrix, return number
+ * of columns.
  */
 GLuint
 _slang_type_dim(slang_type_specifier_type ty)
@@ -906,7 +937,97 @@ _slang_type_dim(slang_type_specifier_type ty)
    case SLANG_SPEC_BVEC4:
    case SLANG_SPEC_MAT4:
       return 4;
+
+   case SLANG_SPEC_MAT23:
+      return 2;
+   case SLANG_SPEC_MAT32:
+      return 3;
+   case SLANG_SPEC_MAT24:
+      return 2;
+   case SLANG_SPEC_MAT42:
+      return 4;
+   case SLANG_SPEC_MAT34:
+      return 3;
+   case SLANG_SPEC_MAT43:
+      return 4;
+
    default:
       return 0;
    }
 }
+
+
+/**
+ * Return the GL_* type that corresponds to a SLANG_SPEC_* type.
+ */
+GLenum
+_slang_gltype_from_specifier(const slang_type_specifier *type)
+{
+   switch (type->type) {
+   case SLANG_SPEC_BOOL:
+      return GL_BOOL;
+   case SLANG_SPEC_BVEC2:
+      return GL_BOOL_VEC2;
+   case SLANG_SPEC_BVEC3:
+      return GL_BOOL_VEC3;
+   case SLANG_SPEC_BVEC4:
+      return GL_BOOL_VEC4;
+   case SLANG_SPEC_INT:
+      return GL_INT;
+   case SLANG_SPEC_IVEC2:
+      return GL_INT_VEC2;
+   case SLANG_SPEC_IVEC3:
+      return GL_INT_VEC3;
+   case SLANG_SPEC_IVEC4:
+      return GL_INT_VEC4;
+   case SLANG_SPEC_FLOAT:
+      return GL_FLOAT;
+   case SLANG_SPEC_VEC2:
+      return GL_FLOAT_VEC2;
+   case SLANG_SPEC_VEC3:
+      return GL_FLOAT_VEC3;
+   case SLANG_SPEC_VEC4:
+      return GL_FLOAT_VEC4;
+   case SLANG_SPEC_MAT2:
+      return GL_FLOAT_MAT2;
+   case SLANG_SPEC_MAT3:
+      return GL_FLOAT_MAT3;
+   case SLANG_SPEC_MAT4:
+      return GL_FLOAT_MAT4;
+   case SLANG_SPEC_MAT23:
+      return GL_FLOAT_MAT2x3;
+   case SLANG_SPEC_MAT32:
+      return GL_FLOAT_MAT3x2;
+   case SLANG_SPEC_MAT24:
+      return GL_FLOAT_MAT2x4;
+   case SLANG_SPEC_MAT42:
+      return GL_FLOAT_MAT4x2;
+   case SLANG_SPEC_MAT34:
+      return GL_FLOAT_MAT3x4;
+   case SLANG_SPEC_MAT43:
+      return GL_FLOAT_MAT4x3;
+   case SLANG_SPEC_SAMPLER1D:
+      return GL_SAMPLER_1D;
+   case SLANG_SPEC_SAMPLER2D:
+      return GL_SAMPLER_2D;
+   case SLANG_SPEC_SAMPLER3D:
+      return GL_SAMPLER_3D;
+   case SLANG_SPEC_SAMPLERCUBE:
+      return GL_SAMPLER_CUBE;
+   case SLANG_SPEC_SAMPLER1DSHADOW:
+      return GL_SAMPLER_1D_SHADOW;
+   case SLANG_SPEC_SAMPLER2DSHADOW:
+      return GL_SAMPLER_2D_SHADOW;
+   case SLANG_SPEC_SAMPLER2DRECT:
+      return GL_SAMPLER_2D_RECT_ARB;
+   case SLANG_SPEC_SAMPLER2DRECTSHADOW:
+      return GL_SAMPLER_2D_RECT_SHADOW_ARB;
+   case SLANG_SPEC_ARRAY:
+      return _slang_gltype_from_specifier(type->_array);
+   case SLANG_SPEC_STRUCT:
+      /* fall-through */
+   default:
+      return GL_NONE;
+   }
+}
+