Home | History | Annotate | Download | only in glsl
      1 /*
      2  * Copyright  2009 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  */
     23 
     24 #include <cstdio>
     25 #include <stdlib.h>
     26 #include "main/core.h" /* for Elements */
     27 #include "glsl_symbol_table.h"
     28 #include "glsl_parser_extras.h"
     29 #include "glsl_types.h"
     30 #include "builtin_types.h"
     31 extern "C" {
     32 #include "program/hash_table.h"
     33 }
     34 
     35 hash_table *glsl_type::array_types = NULL;
     36 hash_table *glsl_type::record_types = NULL;
     37 void *glsl_type::mem_ctx = NULL;
     38 
     39 void
     40 glsl_type::init_hieralloc_type_ctx(void)
     41 {
     42    if (glsl_type::mem_ctx == NULL) {
     43       glsl_type::mem_ctx = hieralloc_autofree_context();
     44       assert(glsl_type::mem_ctx != NULL);
     45    }
     46 }
     47 
     48 glsl_type::glsl_type(GLenum gl_type,
     49 		     glsl_base_type base_type, unsigned vector_elements,
     50 		     unsigned matrix_columns, const char *name) :
     51    gl_type(gl_type),
     52    base_type(base_type),
     53    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
     54    sampler_type(0),
     55    vector_elements(vector_elements), matrix_columns(matrix_columns),
     56    length(0)
     57 {
     58    init_hieralloc_type_ctx();
     59    this->name = hieralloc_strdup(this->mem_ctx, name);
     60    /* Neither dimension is zero or both dimensions are zero.
     61     */
     62    assert((vector_elements == 0) == (matrix_columns == 0));
     63    memset(& fields, 0, sizeof(fields));
     64 }
     65 
     66 glsl_type::glsl_type(GLenum gl_type,
     67 		     enum glsl_sampler_dim dim, bool shadow, bool array,
     68 		     unsigned type, const char *name) :
     69    gl_type(gl_type),
     70    base_type(GLSL_TYPE_SAMPLER),
     71    sampler_dimensionality(dim), sampler_shadow(shadow),
     72    sampler_array(array), sampler_type(type),
     73    vector_elements(0), matrix_columns(0),
     74    length(0)
     75 {
     76    init_hieralloc_type_ctx();
     77    this->name = hieralloc_strdup(this->mem_ctx, name);
     78    memset(& fields, 0, sizeof(fields));
     79 }
     80 
     81 glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
     82 		     const char *name) :
     83    base_type(GLSL_TYPE_STRUCT),
     84    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
     85    sampler_type(0),
     86    vector_elements(0), matrix_columns(0),
     87    length(num_fields)
     88 {
     89    unsigned int i;
     90 
     91    init_hieralloc_type_ctx();
     92    this->name = hieralloc_strdup(this->mem_ctx, name);
     93    this->fields.structure = hieralloc_array(this->mem_ctx,
     94 					 glsl_struct_field, length);
     95    for (i = 0; i < length; i++) {
     96       this->fields.structure[i].type = fields[i].type;
     97       this->fields.structure[i].name = hieralloc_strdup(this->fields.structure,
     98 						     fields[i].name);
     99    }
    100 }
    101 
    102 static void
    103 add_types_to_symbol_table(glsl_symbol_table *symtab,
    104 			  const struct glsl_type *types,
    105 			  unsigned num_types, bool warn)
    106 {
    107    (void) warn;
    108 
    109    for (unsigned i = 0; i < num_types; i++) {
    110       symtab->add_type(types[i].name, & types[i]);
    111    }
    112 }
    113 
    114 void
    115 glsl_type::generate_100ES_types(glsl_symbol_table *symtab)
    116 {
    117    add_types_to_symbol_table(symtab, builtin_core_types,
    118 			     Elements(builtin_core_types),
    119 			     false);
    120    add_types_to_symbol_table(symtab, builtin_structure_types,
    121 			     Elements(builtin_structure_types),
    122 			     false);
    123    add_types_to_symbol_table(symtab, &void_type, 1, false);
    124 }
    125 
    126 void
    127 glsl_type::generate_110_types(glsl_symbol_table *symtab)
    128 {
    129    generate_100ES_types(symtab);
    130 
    131    add_types_to_symbol_table(symtab, builtin_110_types,
    132 			     Elements(builtin_110_types),
    133 			     false);
    134    add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
    135 			     Elements(builtin_110_deprecated_structure_types),
    136 			     false);
    137 }
    138 
    139 
    140 void
    141 glsl_type::generate_120_types(glsl_symbol_table *symtab)
    142 {
    143    generate_110_types(symtab);
    144 
    145    add_types_to_symbol_table(symtab, builtin_120_types,
    146 			     Elements(builtin_120_types), false);
    147 }
    148 
    149 
    150 void
    151 glsl_type::generate_130_types(glsl_symbol_table *symtab)
    152 {
    153    generate_120_types(symtab);
    154 
    155    add_types_to_symbol_table(symtab, builtin_130_types,
    156 			     Elements(builtin_130_types), false);
    157    generate_EXT_texture_array_types(symtab, false);
    158 }
    159 
    160 
    161 void
    162 glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
    163 						bool warn)
    164 {
    165    add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
    166 			     Elements(builtin_ARB_texture_rectangle_types),
    167 			     warn);
    168 }
    169 
    170 
    171 void
    172 glsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab,
    173 					    bool warn)
    174 {
    175    add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
    176 			     Elements(builtin_EXT_texture_array_types),
    177 			     warn);
    178 }
    179 
    180 
    181 void
    182 _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
    183 {
    184    switch (state->language_version) {
    185    case 100:
    186       assert(state->es_shader);
    187       glsl_type::generate_100ES_types(state->symbols);
    188       break;
    189    case 110:
    190       glsl_type::generate_110_types(state->symbols);
    191       break;
    192    case 120:
    193       glsl_type::generate_120_types(state->symbols);
    194       break;
    195    case 130:
    196       glsl_type::generate_130_types(state->symbols);
    197       break;
    198    default:
    199       /* error */
    200       break;
    201    }
    202 
    203    if (state->ARB_texture_rectangle_enable) {
    204       glsl_type::generate_ARB_texture_rectangle_types(state->symbols,
    205 					   state->ARB_texture_rectangle_warn);
    206    }
    207 
    208    if (state->EXT_texture_array_enable && state->language_version < 130) {
    209       // These are already included in 130; don't create twice.
    210       glsl_type::generate_EXT_texture_array_types(state->symbols,
    211 				       state->EXT_texture_array_warn);
    212    }
    213 }
    214 
    215 
    216 const glsl_type *glsl_type::get_base_type() const
    217 {
    218    switch (base_type) {
    219    case GLSL_TYPE_UINT:
    220       return uint_type;
    221    case GLSL_TYPE_INT:
    222       return int_type;
    223    case GLSL_TYPE_FLOAT:
    224       return float_type;
    225    case GLSL_TYPE_BOOL:
    226       return bool_type;
    227    default:
    228       return error_type;
    229    }
    230 }
    231 
    232 
    233 void
    234 _mesa_glsl_release_types(void)
    235 {
    236    if (glsl_type::array_types != NULL) {
    237       hash_table_dtor(glsl_type::array_types);
    238       glsl_type::array_types = NULL;
    239    }
    240 
    241    if (glsl_type::record_types != NULL) {
    242       hash_table_dtor(glsl_type::record_types);
    243       glsl_type::record_types = NULL;
    244    }
    245 }
    246 
    247 
    248 glsl_type::glsl_type(const glsl_type *array, unsigned length) :
    249    base_type(GLSL_TYPE_ARRAY),
    250    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
    251    sampler_type(0),
    252    vector_elements(0), matrix_columns(0),
    253    name(NULL), length(length)
    254 {
    255    this->fields.array = array;
    256    /* Inherit the gl type of the base. The GL type is used for
    257     * uniform/statevar handling in Mesa and the arrayness of the type
    258     * is represented by the size rather than the type.
    259     */
    260    this->gl_type = array->gl_type;
    261 
    262    /* Allow a maximum of 10 characters for the array size.  This is enough
    263     * for 32-bits of ~0.  The extra 3 are for the '[', ']', and terminating
    264     * NUL.
    265     */
    266    const unsigned name_length = strlen(array->name) + 10 + 3;
    267    char *const n = (char *) hieralloc_size(this->mem_ctx, name_length);
    268 
    269    if (length == 0)
    270       snprintf(n, name_length, "%s[]", array->name);
    271    else
    272       snprintf(n, name_length, "%s[%u]", array->name, length);
    273 
    274    this->name = n;
    275 }
    276 
    277 
    278 const glsl_type *
    279 glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
    280 {
    281    if (base_type == GLSL_TYPE_VOID)
    282       return &void_type;
    283 
    284    if ((rows < 1) || (rows > 4) || (columns < 1) || (columns > 4))
    285       return error_type;
    286 
    287    /* Treat GLSL vectors as Nx1 matrices.
    288     */
    289    if (columns == 1) {
    290       switch (base_type) {
    291       case GLSL_TYPE_UINT:
    292 	 return uint_type + (rows - 1);
    293       case GLSL_TYPE_INT:
    294 	 return int_type + (rows - 1);
    295       case GLSL_TYPE_FLOAT:
    296 	 return float_type + (rows - 1);
    297       case GLSL_TYPE_BOOL:
    298 	 return bool_type + (rows - 1);
    299       default:
    300 	 return error_type;
    301       }
    302    } else {
    303       if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1))
    304 	 return error_type;
    305 
    306       /* GLSL matrix types are named mat{COLUMNS}x{ROWS}.  Only the following
    307        * combinations are valid:
    308        *
    309        *   1 2 3 4
    310        * 1
    311        * 2   x x x
    312        * 3   x x x
    313        * 4   x x x
    314        */
    315 #define IDX(c,r) (((c-1)*3) + (r-1))
    316 
    317       switch (IDX(columns, rows)) {
    318       case IDX(2,2): return mat2_type;
    319       case IDX(2,3): return mat2x3_type;
    320       case IDX(2,4): return mat2x4_type;
    321       case IDX(3,2): return mat3x2_type;
    322       case IDX(3,3): return mat3_type;
    323       case IDX(3,4): return mat3x4_type;
    324       case IDX(4,2): return mat4x2_type;
    325       case IDX(4,3): return mat4x3_type;
    326       case IDX(4,4): return mat4_type;
    327       default: return error_type;
    328       }
    329    }
    330 
    331    assert(!"Should not get here.");
    332    return error_type;
    333 }
    334 
    335 
    336 const glsl_type *
    337 glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
    338 {
    339 
    340    if (array_types == NULL) {
    341       array_types = hash_table_ctor(64, hash_table_string_hash,
    342 				    hash_table_string_compare);
    343    }
    344 
    345    /* Generate a name using the base type pointer in the key.  This is
    346     * done because the name of the base type may not be unique across
    347     * shaders.  For example, two shaders may have different record types
    348     * named 'foo'.
    349     */
    350    char key[128];
    351    snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size);
    352 
    353    const glsl_type *t = (glsl_type *) hash_table_find(array_types, key);
    354    if (t == NULL) {
    355       t = new glsl_type(base, array_size);
    356 
    357       hash_table_insert(array_types, (void *) t, hieralloc_strdup(mem_ctx, key));
    358    }
    359 
    360    assert(t->base_type == GLSL_TYPE_ARRAY);
    361    assert(t->length == array_size);
    362    assert(t->fields.array == base);
    363 
    364    return t;
    365 }
    366 
    367 
    368 int
    369 glsl_type::record_key_compare(const void *a, const void *b)
    370 {
    371    const glsl_type *const key1 = (glsl_type *) a;
    372    const glsl_type *const key2 = (glsl_type *) b;
    373 
    374    /* Return zero is the types match (there is zero difference) or non-zero
    375     * otherwise.
    376     */
    377    if (strcmp(key1->name, key2->name) != 0)
    378       return 1;
    379 
    380    if (key1->length != key2->length)
    381       return 1;
    382 
    383    for (unsigned i = 0; i < key1->length; i++) {
    384       if (key1->fields.structure[i].type != key2->fields.structure[i].type)
    385 	 return 1;
    386       if (strcmp(key1->fields.structure[i].name,
    387 		 key2->fields.structure[i].name) != 0)
    388 	 return 1;
    389    }
    390 
    391    return 0;
    392 }
    393 
    394 
    395 unsigned
    396 glsl_type::record_key_hash(const void *a)
    397 {
    398    const glsl_type *const key = (glsl_type *) a;
    399    char hash_key[128];
    400    unsigned size = 0;
    401 
    402    size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length);
    403 
    404    for (unsigned i = 0; i < key->length; i++) {
    405       if (size >= sizeof(hash_key))
    406 	 break;
    407 
    408       size += snprintf(& hash_key[size], sizeof(hash_key) - size,
    409 		       "%p", (void *) key->fields.structure[i].type);
    410    }
    411 
    412    return hash_table_string_hash(& hash_key);
    413 }
    414 
    415 
    416 const glsl_type *
    417 glsl_type::get_record_instance(const glsl_struct_field *fields,
    418 			       unsigned num_fields,
    419 			       const char *name)
    420 {
    421    const glsl_type key(fields, num_fields, name);
    422 
    423    if (record_types == NULL) {
    424       record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
    425    }
    426 
    427    const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
    428    if (t == NULL) {
    429       t = new glsl_type(fields, num_fields, name);
    430 
    431       hash_table_insert(record_types, (void *) t, t);
    432    }
    433 
    434    assert(t->base_type == GLSL_TYPE_STRUCT);
    435    assert(t->length == num_fields);
    436    assert(strcmp(t->name, name) == 0);
    437 
    438    return t;
    439 }
    440 
    441 
    442 const glsl_type *
    443 glsl_type::field_type(const char *name) const
    444 {
    445    if (this->base_type != GLSL_TYPE_STRUCT)
    446       return error_type;
    447 
    448    for (unsigned i = 0; i < this->length; i++) {
    449       if (strcmp(name, this->fields.structure[i].name) == 0)
    450 	 return this->fields.structure[i].type;
    451    }
    452 
    453    return error_type;
    454 }
    455 
    456 
    457 int
    458 glsl_type::field_index(const char *name) const
    459 {
    460    if (this->base_type != GLSL_TYPE_STRUCT)
    461       return -1;
    462 
    463    for (unsigned i = 0; i < this->length; i++) {
    464       if (strcmp(name, this->fields.structure[i].name) == 0)
    465 	 return i;
    466    }
    467 
    468    return -1;
    469 }
    470 
    471 
    472 unsigned
    473 glsl_type::component_slots() const
    474 {
    475    switch (this->base_type) {
    476    case GLSL_TYPE_UINT:
    477    case GLSL_TYPE_INT:
    478    case GLSL_TYPE_FLOAT:
    479    case GLSL_TYPE_BOOL:
    480       return this->components();
    481 
    482    case GLSL_TYPE_STRUCT: {
    483       unsigned size = 0;
    484 
    485       for (unsigned i = 0; i < this->length; i++)
    486 	 size += this->fields.structure[i].type->component_slots();
    487 
    488       return size;
    489    }
    490 
    491    case GLSL_TYPE_ARRAY:
    492       return this->length * this->fields.array->component_slots();
    493 
    494    default:
    495       return 0;
    496    }
    497 }
    498