On Mon, Jun 2, 2014 at 5:05 AM, Tapani Pälli <tapani.pa...@intel.com> wrote: > Will be utilized by IR deserialization for binary shaders. > > Signed-off-by: Tapani Pälli <tapani.pa...@intel.com> > --- > src/glsl/glsl_types.cpp | 106 > ++++++++++++++++++++++++++++++++++++++++++++++++ > src/glsl/glsl_types.h | 19 +++++++++ > 2 files changed, 125 insertions(+) > > diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp > index 212d533..1b96a98 100644 > --- a/src/glsl/glsl_types.cpp > +++ b/src/glsl/glsl_types.cpp > @@ -201,6 +201,112 @@ serilization_epilogue: > } > > > +const glsl_type * > +deserialize_glsl_type(memory_map *map, struct _mesa_glsl_parse_state *state, > + struct hash_table *type_hash) > +{ > + char *name = map->read_string(); > + uint32_t type_size = map->read_uint32_t(); > + const glsl_type *ret_type = glsl_type::error_type; > + > + const glsl_type *existing_type = > + state->symbols->get_type(name); > + > + /* If type exists, move read pointer forward and return type. */ > + if (existing_type) { > + map->ffwd(type_size); > + return existing_type; > + } > + > + /* Has this user type been read and stored to hash already? */ > + uint8_t user_type_exists = map->read_uint8_t(); > + uint32_t type_id = map->read_uint32_t(); > + > + uint32_t length; > + uint8_t base_type, interface_packing; > + > + if (user_type_exists) { > + hash_entry *entry = > + _mesa_hash_table_search(type_hash, _mesa_hash_string(name), > + (void*) (uintptr_t) type_id); > + > + /* Return already read type from the hash. */ > + if (entry && entry->data) > + return (const glsl_type *) entry->data; > + else > + goto type_serialization_error; > + } > + > + length = map->read_uint32_t(); > + base_type = map->read_uint8_t(); > + interface_packing = map->read_uint8_t(); > + > + if (base_type >= GLSL_TYPE_ERROR) > + goto type_serialization_error; > + > + /* Array type has additional element_type information. */ > + if (base_type == GLSL_TYPE_ARRAY) { > + const glsl_type *element_type = > + deserialize_glsl_type(map, state, type_hash); > + if (!element_type) > + goto type_serialization_error; > + > + ret_type = glsl_type::get_array_instance(element_type, length); > + goto return_type; > + } > + > + /* Structures have fields containing of names and types. */ > + else if (base_type == GLSL_TYPE_STRUCT || > + base_type == GLSL_TYPE_INTERFACE) { > + glsl_struct_field *fields = ralloc_array(NULL, glsl_struct_field, > length); > + if (!fields) > + goto type_serialization_error; > + > + for (unsigned k = 0; k < length; k++) { > + map->read(&fields[k], sizeof(glsl_struct_field)); > + char *field_name = map->read_string(); > + fields[k].name = _mesa_strdup(field_name); > + fields[k].type = deserialize_glsl_type(map, state, type_hash); > + /* Break out of the loop if read errors occured. */ > + if (map->errors()) > + goto type_serialization_error; > + } > + > + if (base_type == GLSL_TYPE_STRUCT) > + ret_type = glsl_type::get_record_instance(fields, length, name); > + else if (base_type == GLSL_TYPE_INTERFACE) > + ret_type = > + glsl_type::get_interface_instance(fields, length, > + (glsl_interface_packing) > + interface_packing, name); > + /* Free allocated memory. */ > + for (unsigned k = 0; k < length; k++) > + free((void *)fields[k].name); > + ralloc_free(fields); > + > + goto return_type; > + } > + > + /* Should not fall down here! */ > + goto type_serialization_error; > +
If you reverse the order of the two blocks below, you can get rid of this goto. > +return_type: > + > + /* Store user type in to hash. */ > + _mesa_hash_table_insert(type_hash, _mesa_hash_string(name), > + (void*) (uintptr_t) type_id, > + (void*) ret_type); > + return ret_type; > + > +type_serialization_error: > + > + assert(!"error deserializing glsl_type"); > + return glsl_type::error_type; > +} _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev