#include "glsl_symbol_table.h"
#include "glsl_parser_extras.h"
#include "glsl_types.h"
-#include "builtin_types.h"
extern "C" {
#include "program/hash_table.h"
}
length(0)
{
init_ralloc_type_ctx();
+ assert(name != NULL);
this->name = ralloc_strdup(this->mem_ctx, name);
/* Neither dimension is zero or both dimensions are zero.
*/
length(0)
{
init_ralloc_type_ctx();
+ assert(name != NULL);
this->name = ralloc_strdup(this->mem_ctx, name);
memset(& fields, 0, sizeof(fields));
}
unsigned int i;
init_ralloc_type_ctx();
+ assert(name != NULL);
this->name = ralloc_strdup(this->mem_ctx, name);
this->fields.structure = ralloc_array(this->mem_ctx,
glsl_struct_field, length);
this->fields.structure[i].type = fields[i].type;
this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
fields[i].name);
+ this->fields.structure[i].location = fields[i].location;
+ this->fields.structure[i].interpolation = fields[i].interpolation;
+ this->fields.structure[i].centroid = fields[i].centroid;
+ this->fields.structure[i].sample = fields[i].sample;
this->fields.structure[i].row_major = fields[i].row_major;
}
}
unsigned int i;
init_ralloc_type_ctx();
+ assert(name != NULL);
this->name = ralloc_strdup(this->mem_ctx, name);
this->fields.structure = ralloc_array(this->mem_ctx,
glsl_struct_field, length);
this->fields.structure[i].type = fields[i].type;
this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
fields[i].name);
+ this->fields.structure[i].location = fields[i].location;
+ this->fields.structure[i].interpolation = fields[i].interpolation;
+ this->fields.structure[i].centroid = fields[i].centroid;
+ this->fields.structure[i].sample = fields[i].sample;
this->fields.structure[i].row_major = fields[i].row_major;
}
}
-static void
-add_types_to_symbol_table(glsl_symbol_table *symtab,
- const struct glsl_type *types,
- unsigned num_types, bool warn,
- bool skip_1d)
-{
- (void) warn;
-
- for (unsigned i = 0; i < num_types; i++) {
- if (skip_1d && types[i].base_type == GLSL_TYPE_SAMPLER
- && types[i].sampler_dimensionality == GLSL_SAMPLER_DIM_1D)
- continue;
-
- symtab->add_type(types[i].name, & types[i]);
- }
-}
bool
glsl_type::contains_sampler() const
}
}
+bool
+glsl_type::contains_opaque() const {
+ switch (base_type) {
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_ATOMIC_UINT:
+ return true;
+ case GLSL_TYPE_ARRAY:
+ return element_type()->contains_opaque();
+ case GLSL_TYPE_STRUCT:
+ for (unsigned int i = 0; i < length; i++) {
+ if (fields.structure[i].type->contains_opaque())
+ return true;
+ }
+ return false;
+ default:
+ return false;
+ }
+}
gl_texture_index
glsl_type::sampler_index() const
return TEXTURE_BUFFER_INDEX;
case GLSL_SAMPLER_DIM_EXTERNAL:
return TEXTURE_EXTERNAL_INDEX;
+ case GLSL_SAMPLER_DIM_MS:
+ return (t->sampler_array) ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX : TEXTURE_2D_MULTISAMPLE_INDEX;
default:
assert(!"Should not get here.");
return TEXTURE_BUFFER_INDEX;
}
}
-void
-glsl_type::generate_100ES_types(glsl_symbol_table *symtab)
-{
- bool skip_1d = false;
- add_types_to_symbol_table(symtab, builtin_core_types,
- Elements(builtin_core_types),
- false, skip_1d);
- add_types_to_symbol_table(symtab, builtin_structure_types,
- Elements(builtin_structure_types),
- false, skip_1d);
- add_types_to_symbol_table(symtab, void_type, 1, false, skip_1d);
-}
-
-void
-glsl_type::generate_300ES_types(glsl_symbol_table *symtab)
-{
- /* GLSL 3.00 ES types are the same as GLSL 1.30 types, except that 1D
- * samplers are skipped, and samplerCubeShadow is added.
- */
- bool add_deprecated = false;
- bool skip_1d = true;
-
- generate_130_types(symtab, add_deprecated, skip_1d);
-
- add_types_to_symbol_table(symtab, &_samplerCubeShadow_type, 1, false,
- skip_1d);
-}
-
-void
-glsl_type::generate_110_types(glsl_symbol_table *symtab, bool add_deprecated,
- bool skip_1d)
-{
- generate_100ES_types(symtab);
-
- add_types_to_symbol_table(symtab, builtin_110_types,
- Elements(builtin_110_types),
- false, skip_1d);
- add_types_to_symbol_table(symtab, &_sampler3D_type, 1, false, skip_1d);
- if (add_deprecated) {
- add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
- Elements(builtin_110_deprecated_structure_types),
- false, skip_1d);
- }
-}
-
-
-void
-glsl_type::generate_120_types(glsl_symbol_table *symtab, bool add_deprecated,
- bool skip_1d)
-{
- generate_110_types(symtab, add_deprecated, skip_1d);
-
- add_types_to_symbol_table(symtab, builtin_120_types,
- Elements(builtin_120_types), false, skip_1d);
-}
-
-
-void
-glsl_type::generate_130_types(glsl_symbol_table *symtab, bool add_deprecated,
- bool skip_1d)
-{
- generate_120_types(symtab, add_deprecated, skip_1d);
-
- add_types_to_symbol_table(symtab, builtin_130_types,
- Elements(builtin_130_types), false, skip_1d);
- generate_EXT_texture_array_types(symtab, false);
-}
-
-
-void
-glsl_type::generate_140_types(glsl_symbol_table *symtab)
-{
- bool skip_1d = false;
-
- generate_130_types(symtab, false, skip_1d);
-
- add_types_to_symbol_table(symtab, builtin_140_types,
- Elements(builtin_140_types), false, skip_1d);
-
- add_types_to_symbol_table(symtab, builtin_EXT_texture_buffer_object_types,
- Elements(builtin_EXT_texture_buffer_object_types),
- false, skip_1d);
-}
-
-
-void
-glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
- bool warn)
-{
- bool skip_1d = false;
-
- add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
- Elements(builtin_ARB_texture_rectangle_types),
- warn, skip_1d);
-}
-
-
-void
-glsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab,
- bool warn)
-{
- bool skip_1d = false;
-
- add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
- Elements(builtin_EXT_texture_array_types),
- warn, skip_1d);
-}
-
-
-void
-glsl_type::generate_OES_texture_3D_types(glsl_symbol_table *symtab, bool warn)
-{
- bool skip_1d = false;
-
- add_types_to_symbol_table(symtab, &_sampler3D_type, 1, warn, skip_1d);
-}
-
-
-void
-glsl_type::generate_OES_EGL_image_external_types(glsl_symbol_table *symtab,
- bool warn)
-{
- bool skip_1d = false;
-
- add_types_to_symbol_table(symtab, builtin_OES_EGL_image_external_types,
- Elements(builtin_OES_EGL_image_external_types),
- warn, skip_1d);
-}
-
-void
-glsl_type::generate_ARB_texture_cube_map_array_types(glsl_symbol_table *symtab,
- bool warn)
-{
- bool skip_1d = false;
-
- add_types_to_symbol_table(symtab, builtin_ARB_texture_cube_map_array_types,
- Elements(builtin_ARB_texture_cube_map_array_types),
- warn, skip_1d);
-}
-
-void
-_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
-{
- if (state->es_shader) {
- switch (state->language_version) {
- case 100:
- assert(state->es_shader);
- glsl_type::generate_100ES_types(state->symbols);
- break;
- case 300:
- glsl_type::generate_300ES_types(state->symbols);
- break;
- default:
- assert(!"Unexpected language version");
- break;
- }
- } else {
- bool skip_1d = false;
- switch (state->language_version) {
- case 110:
- glsl_type::generate_110_types(state->symbols, true, skip_1d);
- break;
- case 120:
- glsl_type::generate_120_types(state->symbols, true, skip_1d);
- break;
- case 130:
- glsl_type::generate_130_types(state->symbols, true, skip_1d);
- break;
- case 140:
- case 150:
- glsl_type::generate_140_types(state->symbols);
- break;
- default:
- assert(!"Unexpected language version");
- break;
- }
- }
-
- if (state->ARB_texture_rectangle_enable ||
- state->is_version(140, 0)) {
- glsl_type::generate_ARB_texture_rectangle_types(state->symbols,
- state->ARB_texture_rectangle_warn);
- }
- if (state->OES_texture_3D_enable
- && state->is_version(0, 100)) {
- glsl_type::generate_OES_texture_3D_types(state->symbols,
- state->OES_texture_3D_warn);
- }
-
- if (state->EXT_texture_array_enable
- && !state->is_version(130, 0)) {
- // These are already included in 130; don't create twice.
- glsl_type::generate_EXT_texture_array_types(state->symbols,
- state->EXT_texture_array_warn);
- }
-
- /* We cannot check for language_version == 100 here because we need the
- * types to support fixed-function program generation. But this is fine
- * since the extension is never enabled for OpenGL contexts.
- */
- if (state->OES_EGL_image_external_enable) {
- glsl_type::generate_OES_EGL_image_external_types(state->symbols,
- state->OES_EGL_image_external_warn);
- }
-
- if (state->ARB_texture_cube_map_array_enable) {
- glsl_type::generate_ARB_texture_cube_map_array_types(state->symbols,
- state->ARB_texture_cube_map_array_warn);
- }
-}
-
const glsl_type *glsl_type::get_base_type() const
{
return int_type;
case GLSL_TYPE_FLOAT:
return float_type;
+ case GLSL_TYPE_BOOL:
+ return bool_type;
default:
/* Handle everything else */
return type;
}
+const glsl_type *
+glsl_type::vec(unsigned components)
+{
+ if (components == 0 || components > 4)
+ return error_type;
+
+ static const glsl_type *const ts[] = {
+ float_type, vec2_type, vec3_type, vec4_type
+ };
+ return ts[components - 1];
+}
+
+
+const glsl_type *
+glsl_type::ivec(unsigned components)
+{
+ if (components == 0 || components > 4)
+ return error_type;
+
+ static const glsl_type *const ts[] = {
+ int_type, ivec2_type, ivec3_type, ivec4_type
+ };
+ return ts[components - 1];
+}
+
+
+const glsl_type *
+glsl_type::uvec(unsigned components)
+{
+ if (components == 0 || components > 4)
+ return error_type;
+
+ static const glsl_type *const ts[] = {
+ uint_type, uvec2_type, uvec3_type, uvec4_type
+ };
+ return ts[components - 1];
+}
+
+
+const glsl_type *
+glsl_type::bvec(unsigned components)
+{
+ if (components == 0 || components > 4)
+ return error_type;
+
+ static const glsl_type *const ts[] = {
+ bool_type, bvec2_type, bvec3_type, bvec4_type
+ };
+ return ts[components - 1];
+}
+
+
const glsl_type *
glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
{
if (columns == 1) {
switch (base_type) {
case GLSL_TYPE_UINT:
- return uint_type + (rows - 1);
+ return uvec(rows);
case GLSL_TYPE_INT:
- return int_type + (rows - 1);
+ return ivec(rows);
case GLSL_TYPE_FLOAT:
- return float_type + (rows - 1);
+ return vec(rows);
case GLSL_TYPE_BOOL:
- return bool_type + (rows - 1);
+ return bvec(rows);
default:
return error_type;
}
if (key1->fields.structure[i].row_major
!= key2->fields.structure[i].row_major)
return 1;
+ if (key1->fields.structure[i].location
+ != key2->fields.structure[i].location)
+ return 1;
+ if (key1->fields.structure[i].interpolation
+ != key2->fields.structure[i].interpolation)
+ return 1;
+ if (key1->fields.structure[i].centroid
+ != key2->fields.structure[i].centroid)
+ return 1;
+ if (key1->fields.structure[i].sample
+ != key2->fields.structure[i].sample)
+ return 1;
}
return 0;
glsl_type::get_interface_instance(const glsl_struct_field *fields,
unsigned num_fields,
enum glsl_interface_packing packing,
- const char *name)
+ const char *block_name)
{
- const glsl_type key(fields, num_fields, packing, name);
+ const glsl_type key(fields, num_fields, packing, block_name);
if (interface_types == NULL) {
interface_types = hash_table_ctor(64, record_key_hash, record_key_compare);
const glsl_type *t = (glsl_type *) hash_table_find(interface_types, & key);
if (t == NULL) {
- t = new glsl_type(fields, num_fields, packing, name);
+ t = new glsl_type(fields, num_fields, packing, block_name);
hash_table_insert(interface_types, (void *) t, t);
}
assert(t->base_type == GLSL_TYPE_INTERFACE);
assert(t->length == num_fields);
- assert(strcmp(t->name, name) == 0);
+ assert(strcmp(t->name, block_name) == 0);
return t;
}
return this->length * this->fields.array->component_slots();
case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_VOID:
case GLSL_TYPE_ERROR:
break;
assert(!"not reached");
return -1;
}
+
+
+unsigned
+glsl_type::count_attribute_slots() const
+{
+ /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "A scalar input counts the same amount against this limit as a vec4,
+ * so applications may want to consider packing groups of four
+ * unrelated float inputs together into a vector to better utilize the
+ * capabilities of the underlying hardware. A matrix input will use up
+ * multiple locations. The number of locations used will equal the
+ * number of columns in the matrix."
+ *
+ * The spec does not explicitly say how arrays are counted. However, it
+ * should be safe to assume the total number of slots consumed by an array
+ * is the number of entries in the array multiplied by the number of slots
+ * consumed by a single element of the array.
+ *
+ * The spec says nothing about how structs are counted, because vertex
+ * attributes are not allowed to be (or contain) structs. However, Mesa
+ * allows varying structs, the number of varying slots taken up by a
+ * varying struct is simply equal to the sum of the number of slots taken
+ * up by each element.
+ */
+ switch (this->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_BOOL:
+ return this->matrix_columns;
+
+ case GLSL_TYPE_STRUCT:
+ case GLSL_TYPE_INTERFACE: {
+ unsigned size = 0;
+
+ for (unsigned i = 0; i < this->length; i++)
+ size += this->fields.structure[i].type->count_attribute_slots();
+
+ return size;
+ }
+
+ case GLSL_TYPE_ARRAY:
+ return this->length * this->fields.array->count_attribute_slots();
+
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_ATOMIC_UINT:
+ case GLSL_TYPE_VOID:
+ case GLSL_TYPE_ERROR:
+ break;
+ }
+
+ assert(!"Unexpected type in count_attribute_slots()");
+
+ return 0;
+}
+
+int
+glsl_type::sampler_coordinate_components() const
+{
+ assert(is_sampler());
+
+ int size;
+
+ switch (sampler_dimensionality) {
+ case GLSL_SAMPLER_DIM_1D:
+ case GLSL_SAMPLER_DIM_BUF:
+ size = 1;
+ break;
+ case GLSL_SAMPLER_DIM_2D:
+ case GLSL_SAMPLER_DIM_RECT:
+ case GLSL_SAMPLER_DIM_MS:
+ case GLSL_SAMPLER_DIM_EXTERNAL:
+ size = 2;
+ break;
+ case GLSL_SAMPLER_DIM_3D:
+ case GLSL_SAMPLER_DIM_CUBE:
+ size = 3;
+ break;
+ default:
+ assert(!"Should not get here.");
+ size = 1;
+ break;
+ }
+
+ /* Array textures need an additional component for the array index. */
+ if (sampler_array)
+ size += 1;
+
+ return size;
+}