Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 <stdio.h>
  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. extern "C" {
  31. #include "program/hash_table.h"
  32. }
  33.  
  34. hash_table *glsl_type::array_types = NULL;
  35. hash_table *glsl_type::record_types = NULL;
  36. hash_table *glsl_type::interface_types = NULL;
  37. void *glsl_type::mem_ctx = NULL;
  38.  
  39. void
  40. glsl_type::init_ralloc_type_ctx(void)
  41. {
  42.    if (glsl_type::mem_ctx == NULL) {
  43.       glsl_type::mem_ctx = ralloc_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), interface_packing(0),
  55.    vector_elements(vector_elements), matrix_columns(matrix_columns),
  56.    length(0)
  57. {
  58.    init_ralloc_type_ctx();
  59.    assert(name != NULL);
  60.    this->name = ralloc_strdup(this->mem_ctx, name);
  61.    /* Neither dimension is zero or both dimensions are zero.
  62.     */
  63.    assert((vector_elements == 0) == (matrix_columns == 0));
  64.    memset(& fields, 0, sizeof(fields));
  65. }
  66.  
  67. glsl_type::glsl_type(GLenum gl_type,
  68.                      enum glsl_sampler_dim dim, bool shadow, bool array,
  69.                      unsigned type, const char *name) :
  70.    gl_type(gl_type),
  71.    base_type(GLSL_TYPE_SAMPLER),
  72.    sampler_dimensionality(dim), sampler_shadow(shadow),
  73.    sampler_array(array), sampler_type(type), interface_packing(0),
  74.    vector_elements(0), matrix_columns(0),
  75.    length(0)
  76. {
  77.    init_ralloc_type_ctx();
  78.    assert(name != NULL);
  79.    this->name = ralloc_strdup(this->mem_ctx, name);
  80.    memset(& fields, 0, sizeof(fields));
  81. }
  82.  
  83. glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
  84.                      const char *name) :
  85.    gl_type(0),
  86.    base_type(GLSL_TYPE_STRUCT),
  87.    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
  88.    sampler_type(0), interface_packing(0),
  89.    vector_elements(0), matrix_columns(0),
  90.    length(num_fields)
  91. {
  92.    unsigned int i;
  93.  
  94.    init_ralloc_type_ctx();
  95.    assert(name != NULL);
  96.    this->name = ralloc_strdup(this->mem_ctx, name);
  97.    this->fields.structure = ralloc_array(this->mem_ctx,
  98.                                          glsl_struct_field, length);
  99.    for (i = 0; i < length; i++) {
  100.       this->fields.structure[i].type = fields[i].type;
  101.       this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
  102.                                                      fields[i].name);
  103.       this->fields.structure[i].row_major = fields[i].row_major;
  104.    }
  105. }
  106.  
  107. glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
  108.                      enum glsl_interface_packing packing, const char *name) :
  109.    gl_type(0),
  110.    base_type(GLSL_TYPE_INTERFACE),
  111.    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
  112.    sampler_type(0), interface_packing((unsigned) packing),
  113.    vector_elements(0), matrix_columns(0),
  114.    length(num_fields)
  115. {
  116.    unsigned int i;
  117.  
  118.    init_ralloc_type_ctx();
  119.    assert(name != NULL);
  120.    this->name = ralloc_strdup(this->mem_ctx, name);
  121.    this->fields.structure = ralloc_array(this->mem_ctx,
  122.                                          glsl_struct_field, length);
  123.    for (i = 0; i < length; i++) {
  124.       this->fields.structure[i].type = fields[i].type;
  125.       this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
  126.                                                      fields[i].name);
  127.       this->fields.structure[i].row_major = fields[i].row_major;
  128.    }
  129. }
  130.  
  131.  
  132. bool
  133. glsl_type::contains_sampler() const
  134. {
  135.    if (this->is_array()) {
  136.       return this->fields.array->contains_sampler();
  137.    } else if (this->is_record()) {
  138.       for (unsigned int i = 0; i < this->length; i++) {
  139.          if (this->fields.structure[i].type->contains_sampler())
  140.             return true;
  141.       }
  142.       return false;
  143.    } else {
  144.       return this->is_sampler();
  145.    }
  146. }
  147.  
  148.  
  149. bool
  150. glsl_type::contains_integer() const
  151. {
  152.    if (this->is_array()) {
  153.       return this->fields.array->contains_integer();
  154.    } else if (this->is_record()) {
  155.       for (unsigned int i = 0; i < this->length; i++) {
  156.          if (this->fields.structure[i].type->contains_integer())
  157.             return true;
  158.       }
  159.       return false;
  160.    } else {
  161.       return this->is_integer();
  162.    }
  163. }
  164.  
  165.  
  166. gl_texture_index
  167. glsl_type::sampler_index() const
  168. {
  169.    const glsl_type *const t = (this->is_array()) ? this->fields.array : this;
  170.  
  171.    assert(t->is_sampler());
  172.  
  173.    switch (t->sampler_dimensionality) {
  174.    case GLSL_SAMPLER_DIM_1D:
  175.       return (t->sampler_array) ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX;
  176.    case GLSL_SAMPLER_DIM_2D:
  177.       return (t->sampler_array) ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX;
  178.    case GLSL_SAMPLER_DIM_3D:
  179.       return TEXTURE_3D_INDEX;
  180.    case GLSL_SAMPLER_DIM_CUBE:
  181.       return (t->sampler_array) ? TEXTURE_CUBE_ARRAY_INDEX : TEXTURE_CUBE_INDEX;
  182.    case GLSL_SAMPLER_DIM_RECT:
  183.       return TEXTURE_RECT_INDEX;
  184.    case GLSL_SAMPLER_DIM_BUF:
  185.       return TEXTURE_BUFFER_INDEX;
  186.    case GLSL_SAMPLER_DIM_EXTERNAL:
  187.       return TEXTURE_EXTERNAL_INDEX;
  188.    case GLSL_SAMPLER_DIM_MS:
  189.       return (t->sampler_array) ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX : TEXTURE_2D_MULTISAMPLE_INDEX;
  190.    default:
  191.       assert(!"Should not get here.");
  192.       return TEXTURE_BUFFER_INDEX;
  193.    }
  194. }
  195.  
  196.  
  197. const glsl_type *glsl_type::get_base_type() const
  198. {
  199.    switch (base_type) {
  200.    case GLSL_TYPE_UINT:
  201.       return uint_type;
  202.    case GLSL_TYPE_INT:
  203.       return int_type;
  204.    case GLSL_TYPE_FLOAT:
  205.       return float_type;
  206.    case GLSL_TYPE_BOOL:
  207.       return bool_type;
  208.    default:
  209.       return error_type;
  210.    }
  211. }
  212.  
  213.  
  214. const glsl_type *glsl_type::get_scalar_type() const
  215. {
  216.    const glsl_type *type = this;
  217.  
  218.    /* Handle arrays */
  219.    while (type->base_type == GLSL_TYPE_ARRAY)
  220.       type = type->fields.array;
  221.  
  222.    /* Handle vectors and matrices */
  223.    switch (type->base_type) {
  224.    case GLSL_TYPE_UINT:
  225.       return uint_type;
  226.    case GLSL_TYPE_INT:
  227.       return int_type;
  228.    case GLSL_TYPE_FLOAT:
  229.       return float_type;
  230.    case GLSL_TYPE_BOOL:
  231.       return bool_type;
  232.    default:
  233.       /* Handle everything else */
  234.       return type;
  235.    }
  236. }
  237.  
  238.  
  239. void
  240. _mesa_glsl_release_types(void)
  241. {
  242.    if (glsl_type::array_types != NULL) {
  243.       hash_table_dtor(glsl_type::array_types);
  244.       glsl_type::array_types = NULL;
  245.    }
  246.  
  247.    if (glsl_type::record_types != NULL) {
  248.       hash_table_dtor(glsl_type::record_types);
  249.       glsl_type::record_types = NULL;
  250.    }
  251. }
  252.  
  253.  
  254. glsl_type::glsl_type(const glsl_type *array, unsigned length) :
  255.    base_type(GLSL_TYPE_ARRAY),
  256.    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
  257.    sampler_type(0), interface_packing(0),
  258.    vector_elements(0), matrix_columns(0),
  259.    name(NULL), length(length)
  260. {
  261.    this->fields.array = array;
  262.    /* Inherit the gl type of the base. The GL type is used for
  263.     * uniform/statevar handling in Mesa and the arrayness of the type
  264.     * is represented by the size rather than the type.
  265.     */
  266.    this->gl_type = array->gl_type;
  267.  
  268.    /* Allow a maximum of 10 characters for the array size.  This is enough
  269.     * for 32-bits of ~0.  The extra 3 are for the '[', ']', and terminating
  270.     * NUL.
  271.     */
  272.    const unsigned name_length = strlen(array->name) + 10 + 3;
  273.    char *const n = (char *) ralloc_size(this->mem_ctx, name_length);
  274.  
  275.    if (length == 0)
  276.       snprintf(n, name_length, "%s[]", array->name);
  277.    else
  278.       snprintf(n, name_length, "%s[%u]", array->name, length);
  279.  
  280.    this->name = n;
  281. }
  282.  
  283.  
  284. const glsl_type *
  285. glsl_type::vec(unsigned components)
  286. {
  287.    if (components == 0 || components > 4)
  288.       return error_type;
  289.  
  290.    static const glsl_type *const ts[] = {
  291.       float_type, vec2_type, vec3_type, vec4_type
  292.    };
  293.    return ts[components - 1];
  294. }
  295.  
  296.  
  297. const glsl_type *
  298. glsl_type::ivec(unsigned components)
  299. {
  300.    if (components == 0 || components > 4)
  301.       return error_type;
  302.  
  303.    static const glsl_type *const ts[] = {
  304.       int_type, ivec2_type, ivec3_type, ivec4_type
  305.    };
  306.    return ts[components - 1];
  307. }
  308.  
  309.  
  310. const glsl_type *
  311. glsl_type::uvec(unsigned components)
  312. {
  313.    if (components == 0 || components > 4)
  314.       return error_type;
  315.  
  316.    static const glsl_type *const ts[] = {
  317.       uint_type, uvec2_type, uvec3_type, uvec4_type
  318.    };
  319.    return ts[components - 1];
  320. }
  321.  
  322.  
  323. const glsl_type *
  324. glsl_type::bvec(unsigned components)
  325. {
  326.    if (components == 0 || components > 4)
  327.       return error_type;
  328.  
  329.    static const glsl_type *const ts[] = {
  330.       bool_type, bvec2_type, bvec3_type, bvec4_type
  331.    };
  332.    return ts[components - 1];
  333. }
  334.  
  335.  
  336. const glsl_type *
  337. glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
  338. {
  339.    if (base_type == GLSL_TYPE_VOID)
  340.       return void_type;
  341.  
  342.    if ((rows < 1) || (rows > 4) || (columns < 1) || (columns > 4))
  343.       return error_type;
  344.  
  345.    /* Treat GLSL vectors as Nx1 matrices.
  346.     */
  347.    if (columns == 1) {
  348.       switch (base_type) {
  349.       case GLSL_TYPE_UINT:
  350.          return uvec(rows);
  351.       case GLSL_TYPE_INT:
  352.          return ivec(rows);
  353.       case GLSL_TYPE_FLOAT:
  354.          return vec(rows);
  355.       case GLSL_TYPE_BOOL:
  356.          return bvec(rows);
  357.       default:
  358.          return error_type;
  359.       }
  360.    } else {
  361.       if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1))
  362.          return error_type;
  363.  
  364.       /* GLSL matrix types are named mat{COLUMNS}x{ROWS}.  Only the following
  365.        * combinations are valid:
  366.        *
  367.        *   1 2 3 4
  368.        * 1
  369.        * 2   x x x
  370.        * 3   x x x
  371.        * 4   x x x
  372.        */
  373. #define IDX(c,r) (((c-1)*3) + (r-1))
  374.  
  375.       switch (IDX(columns, rows)) {
  376.       case IDX(2,2): return mat2_type;
  377.       case IDX(2,3): return mat2x3_type;
  378.       case IDX(2,4): return mat2x4_type;
  379.       case IDX(3,2): return mat3x2_type;
  380.       case IDX(3,3): return mat3_type;
  381.       case IDX(3,4): return mat3x4_type;
  382.       case IDX(4,2): return mat4x2_type;
  383.       case IDX(4,3): return mat4x3_type;
  384.       case IDX(4,4): return mat4_type;
  385.       default: return error_type;
  386.       }
  387.    }
  388.  
  389.    assert(!"Should not get here.");
  390.    return error_type;
  391. }
  392.  
  393.  
  394. const glsl_type *
  395. glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
  396. {
  397.  
  398.    if (array_types == NULL) {
  399.       array_types = hash_table_ctor(64, hash_table_string_hash,
  400.                                     hash_table_string_compare);
  401.    }
  402.  
  403.    /* Generate a name using the base type pointer in the key.  This is
  404.     * done because the name of the base type may not be unique across
  405.     * shaders.  For example, two shaders may have different record types
  406.     * named 'foo'.
  407.     */
  408.    char key[128];
  409.    snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size);
  410.  
  411.    const glsl_type *t = (glsl_type *) hash_table_find(array_types, key);
  412.    if (t == NULL) {
  413.       t = new glsl_type(base, array_size);
  414.  
  415.       hash_table_insert(array_types, (void *) t, ralloc_strdup(mem_ctx, key));
  416.    }
  417.  
  418.    assert(t->base_type == GLSL_TYPE_ARRAY);
  419.    assert(t->length == array_size);
  420.    assert(t->fields.array == base);
  421.  
  422.    return t;
  423. }
  424.  
  425.  
  426. int
  427. glsl_type::record_key_compare(const void *a, const void *b)
  428. {
  429.    const glsl_type *const key1 = (glsl_type *) a;
  430.    const glsl_type *const key2 = (glsl_type *) b;
  431.  
  432.    /* Return zero is the types match (there is zero difference) or non-zero
  433.     * otherwise.
  434.     */
  435.    if (strcmp(key1->name, key2->name) != 0)
  436.       return 1;
  437.  
  438.    if (key1->length != key2->length)
  439.       return 1;
  440.  
  441.    if (key1->interface_packing != key2->interface_packing)
  442.       return 1;
  443.  
  444.    for (unsigned i = 0; i < key1->length; i++) {
  445.       if (key1->fields.structure[i].type != key2->fields.structure[i].type)
  446.          return 1;
  447.       if (strcmp(key1->fields.structure[i].name,
  448.                  key2->fields.structure[i].name) != 0)
  449.          return 1;
  450.       if (key1->fields.structure[i].row_major
  451.          != key2->fields.structure[i].row_major)
  452.         return 1;
  453.    }
  454.  
  455.    return 0;
  456. }
  457.  
  458.  
  459. unsigned
  460. glsl_type::record_key_hash(const void *a)
  461. {
  462.    const glsl_type *const key = (glsl_type *) a;
  463.    char hash_key[128];
  464.    unsigned size = 0;
  465.  
  466.    size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length);
  467.  
  468.    for (unsigned i = 0; i < key->length; i++) {
  469.       if (size >= sizeof(hash_key))
  470.          break;
  471.  
  472.       size += snprintf(& hash_key[size], sizeof(hash_key) - size,
  473.                        "%p", (void *) key->fields.structure[i].type);
  474.    }
  475.  
  476.    return hash_table_string_hash(& hash_key);
  477. }
  478.  
  479.  
  480. const glsl_type *
  481. glsl_type::get_record_instance(const glsl_struct_field *fields,
  482.                                unsigned num_fields,
  483.                                const char *name)
  484. {
  485.    const glsl_type key(fields, num_fields, name);
  486.  
  487.    if (record_types == NULL) {
  488.       record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
  489.    }
  490.  
  491.    const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
  492.    if (t == NULL) {
  493.       t = new glsl_type(fields, num_fields, name);
  494.  
  495.       hash_table_insert(record_types, (void *) t, t);
  496.    }
  497.  
  498.    assert(t->base_type == GLSL_TYPE_STRUCT);
  499.    assert(t->length == num_fields);
  500.    assert(strcmp(t->name, name) == 0);
  501.  
  502.    return t;
  503. }
  504.  
  505.  
  506. const glsl_type *
  507. glsl_type::get_interface_instance(const glsl_struct_field *fields,
  508.                                   unsigned num_fields,
  509.                                   enum glsl_interface_packing packing,
  510.                                   const char *name)
  511. {
  512.    const glsl_type key(fields, num_fields, packing, name);
  513.  
  514.    if (interface_types == NULL) {
  515.       interface_types = hash_table_ctor(64, record_key_hash, record_key_compare);
  516.    }
  517.  
  518.    const glsl_type *t = (glsl_type *) hash_table_find(interface_types, & key);
  519.    if (t == NULL) {
  520.       t = new glsl_type(fields, num_fields, packing, name);
  521.  
  522.       hash_table_insert(interface_types, (void *) t, t);
  523.    }
  524.  
  525.    assert(t->base_type == GLSL_TYPE_INTERFACE);
  526.    assert(t->length == num_fields);
  527.    assert(strcmp(t->name, name) == 0);
  528.  
  529.    return t;
  530. }
  531.  
  532.  
  533. const glsl_type *
  534. glsl_type::field_type(const char *name) const
  535. {
  536.    if (this->base_type != GLSL_TYPE_STRUCT
  537.        && this->base_type != GLSL_TYPE_INTERFACE)
  538.       return error_type;
  539.  
  540.    for (unsigned i = 0; i < this->length; i++) {
  541.       if (strcmp(name, this->fields.structure[i].name) == 0)
  542.          return this->fields.structure[i].type;
  543.    }
  544.  
  545.    return error_type;
  546. }
  547.  
  548.  
  549. int
  550. glsl_type::field_index(const char *name) const
  551. {
  552.    if (this->base_type != GLSL_TYPE_STRUCT
  553.        && this->base_type != GLSL_TYPE_INTERFACE)
  554.       return -1;
  555.  
  556.    for (unsigned i = 0; i < this->length; i++) {
  557.       if (strcmp(name, this->fields.structure[i].name) == 0)
  558.          return i;
  559.    }
  560.  
  561.    return -1;
  562. }
  563.  
  564.  
  565. unsigned
  566. glsl_type::component_slots() const
  567. {
  568.    switch (this->base_type) {
  569.    case GLSL_TYPE_UINT:
  570.    case GLSL_TYPE_INT:
  571.    case GLSL_TYPE_FLOAT:
  572.    case GLSL_TYPE_BOOL:
  573.       return this->components();
  574.  
  575.    case GLSL_TYPE_STRUCT:
  576.    case GLSL_TYPE_INTERFACE: {
  577.       unsigned size = 0;
  578.  
  579.       for (unsigned i = 0; i < this->length; i++)
  580.          size += this->fields.structure[i].type->component_slots();
  581.  
  582.       return size;
  583.    }
  584.  
  585.    case GLSL_TYPE_ARRAY:
  586.       return this->length * this->fields.array->component_slots();
  587.  
  588.    case GLSL_TYPE_SAMPLER:
  589.    case GLSL_TYPE_VOID:
  590.    case GLSL_TYPE_ERROR:
  591.       break;
  592.    }
  593.  
  594.    return 0;
  595. }
  596.  
  597. bool
  598. glsl_type::can_implicitly_convert_to(const glsl_type *desired) const
  599. {
  600.    if (this == desired)
  601.       return true;
  602.  
  603.    /* There is no conversion among matrix types. */
  604.    if (this->matrix_columns > 1 || desired->matrix_columns > 1)
  605.       return false;
  606.  
  607.    /* int and uint can be converted to float. */
  608.    return desired->is_float()
  609.           && this->is_integer()
  610.           && this->vector_elements == desired->vector_elements;
  611. }
  612.  
  613. unsigned
  614. glsl_type::std140_base_alignment(bool row_major) const
  615. {
  616.    /* (1) If the member is a scalar consuming <N> basic machine units, the
  617.     *     base alignment is <N>.
  618.     *
  619.     * (2) If the member is a two- or four-component vector with components
  620.     *     consuming <N> basic machine units, the base alignment is 2<N> or
  621.     *     4<N>, respectively.
  622.     *
  623.     * (3) If the member is a three-component vector with components consuming
  624.     *     <N> basic machine units, the base alignment is 4<N>.
  625.     */
  626.    if (this->is_scalar() || this->is_vector()) {
  627.       switch (this->vector_elements) {
  628.       case 1:
  629.          return 4;
  630.       case 2:
  631.          return 8;
  632.       case 3:
  633.       case 4:
  634.          return 16;
  635.       }
  636.    }
  637.  
  638.    /* (4) If the member is an array of scalars or vectors, the base alignment
  639.     *     and array stride are set to match the base alignment of a single
  640.     *     array element, according to rules (1), (2), and (3), and rounded up
  641.     *     to the base alignment of a vec4. The array may have padding at the
  642.     *     end; the base offset of the member following the array is rounded up
  643.     *     to the next multiple of the base alignment.
  644.     *
  645.     * (6) If the member is an array of <S> column-major matrices with <C>
  646.     *     columns and <R> rows, the matrix is stored identically to a row of
  647.     *     <S>*<C> column vectors with <R> components each, according to rule
  648.     *     (4).
  649.     *
  650.     * (8) If the member is an array of <S> row-major matrices with <C> columns
  651.     *     and <R> rows, the matrix is stored identically to a row of <S>*<R>
  652.     *     row vectors with <C> components each, according to rule (4).
  653.     *
  654.     * (10) If the member is an array of <S> structures, the <S> elements of
  655.     *      the array are laid out in order, according to rule (9).
  656.     */
  657.    if (this->is_array()) {
  658.       if (this->fields.array->is_scalar() ||
  659.           this->fields.array->is_vector() ||
  660.           this->fields.array->is_matrix()) {
  661.          return MAX2(this->fields.array->std140_base_alignment(row_major), 16);
  662.       } else {
  663.          assert(this->fields.array->is_record());
  664.          return this->fields.array->std140_base_alignment(row_major);
  665.       }
  666.    }
  667.  
  668.    /* (5) If the member is a column-major matrix with <C> columns and
  669.     *     <R> rows, the matrix is stored identically to an array of
  670.     *     <C> column vectors with <R> components each, according to
  671.     *     rule (4).
  672.     *
  673.     * (7) If the member is a row-major matrix with <C> columns and <R>
  674.     *     rows, the matrix is stored identically to an array of <R>
  675.     *     row vectors with <C> components each, according to rule (4).
  676.     */
  677.    if (this->is_matrix()) {
  678.       const struct glsl_type *vec_type, *array_type;
  679.       int c = this->matrix_columns;
  680.       int r = this->vector_elements;
  681.  
  682.       if (row_major) {
  683.          vec_type = get_instance(GLSL_TYPE_FLOAT, c, 1);
  684.          array_type = glsl_type::get_array_instance(vec_type, r);
  685.       } else {
  686.          vec_type = get_instance(GLSL_TYPE_FLOAT, r, 1);
  687.          array_type = glsl_type::get_array_instance(vec_type, c);
  688.       }
  689.  
  690.       return array_type->std140_base_alignment(false);
  691.    }
  692.  
  693.    /* (9) If the member is a structure, the base alignment of the
  694.     *     structure is <N>, where <N> is the largest base alignment
  695.     *     value of any of its members, and rounded up to the base
  696.     *     alignment of a vec4. The individual members of this
  697.     *     sub-structure are then assigned offsets by applying this set
  698.     *     of rules recursively, where the base offset of the first
  699.     *     member of the sub-structure is equal to the aligned offset
  700.     *     of the structure. The structure may have padding at the end;
  701.     *     the base offset of the member following the sub-structure is
  702.     *     rounded up to the next multiple of the base alignment of the
  703.     *     structure.
  704.     */
  705.    if (this->is_record()) {
  706.       unsigned base_alignment = 16;
  707.       for (unsigned i = 0; i < this->length; i++) {
  708.          const struct glsl_type *field_type = this->fields.structure[i].type;
  709.          base_alignment = MAX2(base_alignment,
  710.                                field_type->std140_base_alignment(row_major));
  711.       }
  712.       return base_alignment;
  713.    }
  714.  
  715.    assert(!"not reached");
  716.    return -1;
  717. }
  718.  
  719. unsigned
  720. glsl_type::std140_size(bool row_major) const
  721. {
  722.    /* (1) If the member is a scalar consuming <N> basic machine units, the
  723.     *     base alignment is <N>.
  724.     *
  725.     * (2) If the member is a two- or four-component vector with components
  726.     *     consuming <N> basic machine units, the base alignment is 2<N> or
  727.     *     4<N>, respectively.
  728.     *
  729.     * (3) If the member is a three-component vector with components consuming
  730.     *     <N> basic machine units, the base alignment is 4<N>.
  731.     */
  732.    if (this->is_scalar() || this->is_vector()) {
  733.       return this->vector_elements * 4;
  734.    }
  735.  
  736.    /* (5) If the member is a column-major matrix with <C> columns and
  737.     *     <R> rows, the matrix is stored identically to an array of
  738.     *     <C> column vectors with <R> components each, according to
  739.     *     rule (4).
  740.     *
  741.     * (6) If the member is an array of <S> column-major matrices with <C>
  742.     *     columns and <R> rows, the matrix is stored identically to a row of
  743.     *     <S>*<C> column vectors with <R> components each, according to rule
  744.     *     (4).
  745.     *
  746.     * (7) If the member is a row-major matrix with <C> columns and <R>
  747.     *     rows, the matrix is stored identically to an array of <R>
  748.     *     row vectors with <C> components each, according to rule (4).
  749.     *
  750.     * (8) If the member is an array of <S> row-major matrices with <C> columns
  751.     *     and <R> rows, the matrix is stored identically to a row of <S>*<R>
  752.     *     row vectors with <C> components each, according to rule (4).
  753.     */
  754.    if (this->is_matrix() || (this->is_array() &&
  755.                              this->fields.array->is_matrix())) {
  756.       const struct glsl_type *element_type;
  757.       const struct glsl_type *vec_type;
  758.       unsigned int array_len;
  759.  
  760.       if (this->is_array()) {
  761.          element_type = this->fields.array;
  762.          array_len = this->length;
  763.       } else {
  764.          element_type = this;
  765.          array_len = 1;
  766.       }
  767.  
  768.       if (row_major) {
  769.          vec_type = get_instance(GLSL_TYPE_FLOAT,
  770.                                  element_type->matrix_columns, 1);
  771.          array_len *= element_type->vector_elements;
  772.       } else {
  773.          vec_type = get_instance(GLSL_TYPE_FLOAT,
  774.                                  element_type->vector_elements, 1);
  775.          array_len *= element_type->matrix_columns;
  776.       }
  777.       const glsl_type *array_type = glsl_type::get_array_instance(vec_type,
  778.                                                                   array_len);
  779.  
  780.       return array_type->std140_size(false);
  781.    }
  782.  
  783.    /* (4) If the member is an array of scalars or vectors, the base alignment
  784.     *     and array stride are set to match the base alignment of a single
  785.     *     array element, according to rules (1), (2), and (3), and rounded up
  786.     *     to the base alignment of a vec4. The array may have padding at the
  787.     *     end; the base offset of the member following the array is rounded up
  788.     *     to the next multiple of the base alignment.
  789.     *
  790.     * (10) If the member is an array of <S> structures, the <S> elements of
  791.     *      the array are laid out in order, according to rule (9).
  792.     */
  793.    if (this->is_array()) {
  794.       if (this->fields.array->is_record()) {
  795.          return this->length * this->fields.array->std140_size(row_major);
  796.       } else {
  797.          unsigned element_base_align =
  798.             this->fields.array->std140_base_alignment(row_major);
  799.          return this->length * MAX2(element_base_align, 16);
  800.       }
  801.    }
  802.  
  803.    /* (9) If the member is a structure, the base alignment of the
  804.     *     structure is <N>, where <N> is the largest base alignment
  805.     *     value of any of its members, and rounded up to the base
  806.     *     alignment of a vec4. The individual members of this
  807.     *     sub-structure are then assigned offsets by applying this set
  808.     *     of rules recursively, where the base offset of the first
  809.     *     member of the sub-structure is equal to the aligned offset
  810.     *     of the structure. The structure may have padding at the end;
  811.     *     the base offset of the member following the sub-structure is
  812.     *     rounded up to the next multiple of the base alignment of the
  813.     *     structure.
  814.     */
  815.    if (this->is_record()) {
  816.       unsigned size = 0;
  817.       for (unsigned i = 0; i < this->length; i++) {
  818.          const struct glsl_type *field_type = this->fields.structure[i].type;
  819.          unsigned align = field_type->std140_base_alignment(row_major);
  820.          size = glsl_align(size, align);
  821.          size += field_type->std140_size(row_major);
  822.       }
  823.       size = glsl_align(size,
  824.                         this->fields.structure[0].type->std140_base_alignment(row_major));
  825.       return size;
  826.    }
  827.  
  828.    assert(!"not reached");
  829.    return -1;
  830. }
  831.