This mapping is generally used for mapping the strings identifying uniforms/attributes to integer locations in the GL API. While one would hope that applications just call these once per thing per shader at startup, new app developers often end up calling this at runtime. Having an implementation that's faster at lookup (because there are often more than 16 uniforms) should help those applications. --- src/glsl/Makefile.am | 2 + src/glsl/SConscript | 4 +- src/glsl/glcpp/Makefile.am | 2 + src/mesa/Android.mk | 2 + src/mesa/main/hash_table.h | 1 + src/mesa/program/string_to_uint_map.cpp | 2 +- src/mesa/program/string_to_uint_map.h | 73 +++++++++++++------------------ 7 files changed, 41 insertions(+), 45 deletions(-)
diff --git a/src/glsl/Makefile.am b/src/glsl/Makefile.am index d3eb742..3febf16 100644 --- a/src/glsl/Makefile.am +++ b/src/glsl/Makefile.am @@ -53,6 +53,7 @@ libglslcommon_la_LIBADD = glcpp/libglcpp.la # common sources for builtin_compiler and glsl_compiler GLSL2_SOURCES = \ $(top_srcdir)/src/mesa/program/chaining_hash_table.c \ + $(top_srcdir)/src/mesa/program/hash_table.c \ $(top_srcdir)/src/mesa/program/symbol_table.c \ $(GLSL_COMPILER_CXX_FILES) @@ -69,6 +70,7 @@ glsl_compiler_LDADD = libglsl.la glsl_test_SOURCES = \ $(top_srcdir)/src/mesa/program/chaining_hash_table.c \ + $(top_srcdir)/src/mesa/program/hash_table.c \ $(top_srcdir)/src/mesa/program/symbol_table.c \ $(GLSL_SRCDIR)/standalone_scaffolding.cpp \ test.cpp \ diff --git a/src/glsl/SConscript b/src/glsl/SConscript index b687788..43a3e06 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -58,12 +58,14 @@ if env['crosscompile'] and not env['embedded']: else: # Copy these files to avoid generation object files into src/mesa/program env.Prepend(CPPPATH = ['#src/mesa/program']) - env.Command('hash_table.c', '#src/mesa/program/chaining_hash_table.c', Copy('$TARGET', '$SOURCE')) + env.Command('hash_table.c', '#src/mesa/program/hash_table.c', Copy('$TARGET', '$SOURCE')) + env.Command('chaining_hash_table.c', '#src/mesa/program/chaining_hash_table.c', Copy('$TARGET', '$SOURCE')) env.Command('symbol_table.c', '#src/mesa/program/symbol_table.c', Copy('$TARGET', '$SOURCE')) compiler_objs = env.StaticObject(source_lists['GLSL_COMPILER_CXX_FILES']) mesa_objs = env.StaticObject([ + 'hash_table.c', 'chaining_hash_table.c', 'symbol_table.c', ]) diff --git a/src/glsl/glcpp/Makefile.am b/src/glsl/glcpp/Makefile.am index 3709302..651b0d3 100644 --- a/src/glsl/glcpp/Makefile.am +++ b/src/glsl/glcpp/Makefile.am @@ -26,6 +26,7 @@ AM_CFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/src/mapi \ -I$(top_srcdir)/src/mesa/ \ + -I$(top_srcdir)/src/glsl/ \ $(LIBRARY_INCLUDES) \ $(DEFINES) \ $(LIBRARY_DEFINES) \ @@ -45,6 +46,7 @@ libglcpp_la_SOURCES = \ glcpp_SOURCES = \ ../ralloc.c \ $(top_srcdir)/src/mesa/program/chaining_hash_table.c \ + $(top_srcdir)/src/mesa/program/hash_table.c \ glcpp.c glcpp_LDADD = libglcpp.la diff --git a/src/mesa/Android.mk b/src/mesa/Android.mk index 1cc317a..6b660b5 100644 --- a/src/mesa/Android.mk +++ b/src/mesa/Android.mk @@ -127,6 +127,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := \ program/chaining_hash_table.c \ + program/hash_table.c \ program/symbol_table.c LOCAL_MODULE := libmesa_glsl_utils @@ -142,6 +143,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := \ program/chaining_hash_table.c \ + program/hash_table.c \ program/symbol_table.c LOCAL_MODULE := libmesa_glsl_utils diff --git a/src/mesa/main/hash_table.h b/src/mesa/main/hash_table.h index 78e3aea..f866ecd 100644 --- a/src/mesa/main/hash_table.h +++ b/src/mesa/main/hash_table.h @@ -25,6 +25,7 @@ * */ +#include <sys/types.h> #include <inttypes.h> #include <stdbool.h> diff --git a/src/mesa/program/string_to_uint_map.cpp b/src/mesa/program/string_to_uint_map.cpp index b6a08c2..f893450 100644 --- a/src/mesa/program/string_to_uint_map.cpp +++ b/src/mesa/program/string_to_uint_map.cpp @@ -26,7 +26,7 @@ ` * * \author Ian Romanick <ian.d.roman...@intel.com> */ -#include "hash_table.h" +#include "main/hash_table.h" #include "string_to_uint_map.h" extern "C" struct string_to_uint_map * diff --git a/src/mesa/program/string_to_uint_map.h b/src/mesa/program/string_to_uint_map.h index 8921a6e..49ecd50 100644 --- a/src/mesa/program/string_to_uint_map.h +++ b/src/mesa/program/string_to_uint_map.h @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include "hash_table.h" +#include "main/hash_table.h" #ifdef __cplusplus extern "C" { @@ -40,25 +40,26 @@ string_to_uint_map_dtor(struct string_to_uint_map *); #endif #ifdef __cplusplus +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> + /** * Map from a string (name) to an unsigned integer value - * - * \note - * Because of the way this class interacts with the \c hash_table - * implementation, values of \c UINT_MAX cannot be stored in the map. */ struct string_to_uint_map { public: string_to_uint_map() { - this->ht = hash_table_ctor(0, hash_table_string_hash, - hash_table_string_compare); + this->ht = _mesa_hash_table_create(NULL, + _mesa_key_string_equal); } ~string_to_uint_map() { - hash_table_call_foreach(this->ht, delete_key, NULL); - hash_table_dtor(this->ht); + clear(); + _mesa_hash_table_destroy(this->ht, NULL); } /** @@ -66,8 +67,11 @@ public: */ void clear() { - hash_table_call_foreach(this->ht, delete_key, NULL); - hash_table_clear(this->ht); + struct hash_entry *entry; + hash_table_foreach(this->ht, entry) { + free((void *)entry->key); + _mesa_hash_table_remove(this->ht, entry); + } } /** @@ -82,47 +86,30 @@ public: */ bool get(unsigned &value, const char *key) { - const intptr_t v = - (intptr_t) hash_table_find(this->ht, (const void *) key); + struct hash_entry *entry; + entry = _mesa_hash_table_search(this->ht, _mesa_hash_string(key), key); + if (!entry) + return false; - if (v == 0) - return false; - - value = (unsigned)(v - 1); + value = (uintptr_t)entry->data; return true; } void put(unsigned value, const char *key) { - /* The low-level hash table structure returns NULL if key is not in the - * hash table. However, users of this map might want to store zero as a - * valid value in the table. Bias the value by +1 so that a - * user-specified zero is stored as 1. This enables ::get to tell the - * difference between a user-specified zero (returned as 1 by - * hash_table_find) and the key not in the table (returned as 0 by - * hash_table_find). - * - * The net effect is that we can't store UINT_MAX in the table. This is - * because UINT_MAX+1 = 0. - */ - assert(value != UINT_MAX); - char *dup_key = strdup(key); - bool result = hash_table_replace(this->ht, - (void *) (intptr_t) (value + 1), - dup_key); - if (result) - free(dup_key); + uint32_t hash = _mesa_hash_string(key); + struct hash_entry *entry; + + entry = _mesa_hash_table_search(this->ht, hash, key); + if (entry) { + entry->data = (void *)(uintptr_t)value; + } else { + key = strdup(key); + _mesa_hash_table_insert(this->ht, hash, key, (void *)(uintptr_t)value); + } } private: - static void delete_key(const void *key, void *data, void *closure) - { - (void) data; - (void) closure; - - free((char *)key); - } - struct hash_table *ht; }; #endif /* __cplusplus */ -- 1.7.10.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev