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

Tapani Pälli tapani.palli at intel.com
Mon Jun 2 05:05:49 PDT 2014


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;
+
+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;
+}
+
+
+
+
 bool
 glsl_type::contains_sampler() const
 {
diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h
index bc2dffe..94b2e6c 100644
--- a/src/glsl/glsl_types.h
+++ b/src/glsl/glsl_types.h
@@ -83,6 +83,7 @@ enum glsl_interface_packing {
 #include "GL/gl.h"
 #include "ralloc.h"
 #include "memory_writer.h"
+#include "memory_map.h"
 
 struct glsl_type {
    GLenum gl_type;
@@ -128,6 +129,16 @@ struct glsl_type {
    void serialize(memory_writer &mem) const;
 
    /**
+    * Deserialization functionality used by binary shaders,
+    * state and type_hash are helper structures managed by the
+    * ir_deserializer class.
+    */
+   const glsl_type *deserialize(memory_map *map,
+                                struct _mesa_glsl_parse_state *state,
+                                struct hash_table *type_hash,
+                                uint32_t hash_value);
+
+   /**
     * \name Vector and matrix element counts
     *
     * For scalars, each of these values will be 1.  For non-numeric types
@@ -672,6 +683,14 @@ struct glsl_struct_field {
    unsigned sample:1;
 };
 
+/**
+ * Deserialization utility function used by the binary shaders, state and
+ * type_hash are mandatory helper structures managed by the caller.
+ */
+const glsl_type *
+deserialize_glsl_type(memory_map *map, struct _mesa_glsl_parse_state *state,
+                      struct hash_table *type_hash);
+
 static inline unsigned int
 glsl_align(unsigned int a, unsigned int align)
 {
-- 
1.8.3.1



More information about the mesa-dev mailing list