[Mesa-dev] [RFC 08/20] glsl: glsl_type deserialization

Matt Turner mattst88 at gmail.com
Wed Jun 4 16:52:56 PDT 2014


On Mon, Jun 2, 2014 at 5:05 AM, Tapani Pälli <tapani.palli at intel.com> wrote:
> Will be utilized by IR deserialization for binary shaders.
>
> Signed-off-by: Tapani Pälli <tapani.palli at 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;
> +}


More information about the mesa-dev mailing list