More GLSL code:
[mesa.git] / src / mesa / shader / slang / slang_compile_variable.c
index ff042bb65fc0099ee14c303879ff550e08f41b2d..6f56872b593f70d9149de5f39b3662dd4f0a00da 100644 (file)
@@ -269,7 +269,7 @@ int slang_variable_construct (slang_variable *var)
        if (!slang_fully_specified_type_construct (&var->type))\r
                return 0;\r
        var->a_name = SLANG_ATOM_NULL;\r
-       var->array_size = NULL;\r
+       var->array_len = 0;\r
        var->initializer = NULL;\r
        var->address = ~0;\r
        var->size = 0;\r
@@ -280,11 +280,6 @@ int slang_variable_construct (slang_variable *var)
 void slang_variable_destruct (slang_variable *var)\r
 {\r
        slang_fully_specified_type_destruct (&var->type);\r
-       if (var->array_size != NULL)\r
-       {\r
-               slang_operation_destruct (var->array_size);\r
-               slang_alloc_free (var->array_size);\r
-       }\r
        if (var->initializer != NULL)\r
        {\r
                slang_operation_destruct (var->initializer);\r
@@ -304,26 +299,7 @@ int slang_variable_copy (slang_variable *x, const slang_variable *y)
                return 0;\r
        }\r
        z.a_name = y->a_name;\r
-       if (y->array_size != NULL)\r
-       {\r
-               z.array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));\r
-               if (z.array_size == NULL)\r
-               {\r
-                       slang_variable_destruct (&z);\r
-                       return 0;\r
-               }\r
-               if (!slang_operation_construct (z.array_size))\r
-               {\r
-                       slang_alloc_free (z.array_size);\r
-                       slang_variable_destruct (&z);\r
-                       return 0;\r
-               }\r
-               if (!slang_operation_copy (z.array_size, y->array_size))\r
-               {\r
-                       slang_variable_destruct (&z);\r
-                       return 0;\r
-               }\r
-       }\r
+       z.array_len = y->array_len;\r
        if (y->initializer != NULL)\r
        {\r
                z.initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));\r
@@ -364,3 +340,192 @@ slang_variable *_slang_locate_variable (slang_variable_scope *scope, slang_atom
        return NULL;\r
 }\r
 \r
+/*\r
+ * slang_active_uniforms\r
+ */\r
+\r
+GLvoid slang_active_uniforms_ctr (slang_active_uniforms *self)\r
+{\r
+       self->table = NULL;\r
+       self->count = 0;\r
+}\r
+\r
+GLvoid slang_active_uniforms_dtr (slang_active_uniforms *self)\r
+{\r
+       GLuint i;\r
+\r
+       for (i = 0; i < self->count; i++)\r
+               slang_alloc_free (self->table[i].name);\r
+       slang_alloc_free (self->table);\r
+}\r
+\r
+GLboolean slang_active_uniforms_add (slang_active_uniforms *self, slang_export_data_quant *q,\r
+       const char *name)\r
+{\r
+       const GLuint n = self->count;\r
+\r
+       self->table = (slang_active_uniform *) slang_alloc_realloc (self->table,\r
+               n * sizeof (slang_active_uniform), (n + 1) * sizeof (slang_active_uniform));\r
+       if (self->table == NULL)\r
+               return GL_FALSE;\r
+       self->table[n].quant = q;\r
+       self->table[n].name = slang_string_duplicate (name);\r
+       if (self->table[n].name == NULL)\r
+               return GL_FALSE;\r
+       self->count++;\r
+       return GL_TRUE;\r
+}\r
+\r
+static GLenum gl_type_from_specifier (const slang_type_specifier *type)\r
+{\r
+       switch (type->type)\r
+       {\r
+       case slang_spec_bool:\r
+               return GL_BOOL_ARB;\r
+       case slang_spec_bvec2:\r
+               return GL_BOOL_VEC2_ARB;\r
+       case slang_spec_bvec3:\r
+               return GL_BOOL_VEC3_ARB;\r
+       case slang_spec_bvec4:\r
+               return GL_BOOL_VEC4_ARB;\r
+       case slang_spec_int:\r
+               return GL_INT;\r
+       case slang_spec_ivec2:\r
+               return GL_INT_VEC2_ARB;\r
+       case slang_spec_ivec3:\r
+               return GL_INT_VEC3_ARB;\r
+       case slang_spec_ivec4:\r
+               return GL_INT_VEC4_ARB;\r
+       case slang_spec_float:\r
+               return GL_FLOAT;\r
+       case slang_spec_vec2:\r
+               return GL_FLOAT_VEC2_ARB;\r
+       case slang_spec_vec3:\r
+               return GL_FLOAT_VEC3_ARB;\r
+       case slang_spec_vec4:\r
+               return GL_FLOAT_VEC4_ARB;\r
+       case slang_spec_mat2:\r
+               return GL_FLOAT_MAT2_ARB;\r
+       case slang_spec_mat3:\r
+               return GL_FLOAT_MAT3_ARB;\r
+       case slang_spec_mat4:\r
+               return GL_FLOAT_MAT4_ARB;\r
+       case slang_spec_sampler1D:\r
+               return GL_SAMPLER_1D_ARB;\r
+       case slang_spec_sampler2D:\r
+               return GL_SAMPLER_2D_ARB;\r
+       case slang_spec_sampler3D:\r
+               return GL_SAMPLER_3D_ARB;\r
+       case slang_spec_samplerCube:\r
+               return GL_SAMPLER_CUBE_ARB;\r
+       case slang_spec_sampler1DShadow:\r
+               return GL_SAMPLER_1D_SHADOW_ARB;\r
+       case slang_spec_sampler2DShadow:\r
+               return GL_SAMPLER_2D_SHADOW_ARB;\r
+       case slang_spec_array:\r
+               return gl_type_from_specifier (type->_array);\r
+       default:\r
+               return GL_FLOAT;\r
+       }\r
+}\r
+\r
+static GLboolean build_quant (slang_export_data_quant *q, slang_variable *var)\r
+{\r
+       slang_type_specifier *spec = &var->type.specifier;\r
+\r
+       q->name = var->a_name;\r
+       q->size = var->size;\r
+       if (spec->type == slang_spec_array)\r
+       {\r
+               q->array_len = var->array_len;\r
+               q->size /= var->array_len;\r
+               spec = spec->_array;\r
+       }\r
+       if (spec->type == slang_spec_struct)\r
+       {\r
+               GLuint i;\r
+\r
+               q->u.field_count = spec->_struct->fields->num_variables;\r
+               q->structure = (slang_export_data_quant *) slang_alloc_malloc (\r
+                       q->u.field_count * sizeof (slang_export_data_quant));\r
+               if (q->structure == NULL)\r
+                       return GL_FALSE;\r
+\r
+               for (i = 0; i < q->u.field_count; i++)\r
+                       slang_export_data_quant_ctr (&q->structure[i]);\r
+               for (i = 0; i < q->u.field_count; i++)\r
+                       if (!build_quant (&q->structure[i], &spec->_struct->fields->variables[i]))\r
+                               return GL_FALSE;\r
+       }\r
+       else\r
+               q->u.basic_type = gl_type_from_specifier (spec);\r
+       return GL_TRUE;\r
+}\r
+\r
+GLboolean _slang_build_export_data_table (slang_export_data_table *tbl, slang_variable_scope *vars)\r
+{\r
+       GLuint i;\r
+\r
+       for (i = 0; i < vars->num_variables; i++)\r
+       {\r
+               slang_variable *var = &vars->variables[i];\r
+\r
+               if (var->type.qualifier == slang_qual_uniform)\r
+               {\r
+                       slang_export_data_entry *e = slang_export_data_table_add (tbl);\r
+                       if (e == NULL)\r
+                               return GL_FALSE;\r
+                       if (!build_quant (&e->quant, var))\r
+                               return GL_FALSE;\r
+                       e->access = slang_exp_uniform;\r
+                       e->address = var->address;\r
+               }\r
+       }\r
+\r
+       if (vars->outer_scope != NULL)\r
+               return _slang_build_export_data_table (tbl, vars->outer_scope);\r
+       return GL_TRUE;\r
+}\r
+\r
+static GLboolean insert_uniform (slang_active_uniforms *u, slang_export_data_quant *q, char *name,\r
+       slang_atom_pool *atoms)\r
+{\r
+       slang_string_concat (name, slang_atom_pool_id (atoms, q->name));\r
+       if (q->array_len != 0)\r
+               slang_string_concat (name, "[0]");\r
+\r
+       if (q->structure != NULL)\r
+       {\r
+               GLuint save, i;\r
+\r
+               slang_string_concat (name, ".");\r
+               save = slang_string_length (name);\r
+\r
+               for (i = 0; i < q->u.field_count; i++)\r
+               {\r
+                       if (!insert_uniform (u, &q->structure[i], name, atoms))\r
+                               return GL_FALSE;\r
+                       name[save] = '\0';\r
+               }\r
+\r
+               return GL_TRUE;\r
+       }\r
+\r
+       return slang_active_uniforms_add (u, q, name);\r
+}\r
+\r
+GLboolean _slang_gather_active_uniforms (slang_active_uniforms *u, slang_export_data_table *tbl)\r
+{\r
+       GLuint i;\r
+\r
+       for (i = 0; i < tbl->count; i++)\r
+       {\r
+               char name[1024] = "";\r
+\r
+               if (!insert_uniform (u, &tbl->entries[i].quant, name, tbl->atoms))\r
+                       return GL_FALSE;\r
+       }\r
+\r
+       return GL_TRUE;\r
+}\r
+\r