From 0784c49c0f8fcc8b3abd4c9286d9fd8bc089dd7d Mon Sep 17 00:00:00 2001 From: Jonathan Gray Date: Sun, 22 Nov 2015 02:46:45 +0000 Subject: import Mesa 11.0.6 --- lib/mesa/src/util/Makefile.am | 58 + lib/mesa/src/util/Makefile.in | 1414 ++++++++++++++++++++ lib/mesa/src/util/Makefile.sources | 24 + lib/mesa/src/util/SConscript | 58 + lib/mesa/src/util/bitset.h | 135 ++ lib/mesa/src/util/format_srgb.c | 178 +++ lib/mesa/src/util/format_srgb.h | 149 +++ lib/mesa/src/util/format_srgb.py | 155 +++ lib/mesa/src/util/hash_table.c | 475 +++++++ lib/mesa/src/util/hash_table.h | 137 ++ lib/mesa/src/util/list.h | 211 +++ lib/mesa/src/util/macros.h | 214 +++ lib/mesa/src/util/ralloc.c | 518 +++++++ lib/mesa/src/util/ralloc.h | 452 +++++++ lib/mesa/src/util/register_allocate.c | 712 ++++++++++ lib/mesa/src/util/register_allocate.h | 91 ++ lib/mesa/src/util/rgtc.c | 61 + lib/mesa/src/util/rgtc.h | 39 + lib/mesa/src/util/roundeven_test.c | 140 ++ lib/mesa/src/util/rounding.h | 131 ++ lib/mesa/src/util/set.c | 391 ++++++ lib/mesa/src/util/set.h | 100 ++ lib/mesa/src/util/simple_list.h | 211 +++ lib/mesa/src/util/strtod.c | 85 ++ lib/mesa/src/util/strtod.h | 52 + lib/mesa/src/util/tests/hash_table/Makefile.am | 44 + lib/mesa/src/util/tests/hash_table/Makefile.in | 1326 ++++++++++++++++++ lib/mesa/src/util/tests/hash_table/collision.c | 95 ++ .../src/util/tests/hash_table/delete_and_lookup.c | 76 ++ .../src/util/tests/hash_table/delete_management.c | 90 ++ .../src/util/tests/hash_table/destroy_callback.c | 68 + .../src/util/tests/hash_table/insert_and_lookup.c | 59 + lib/mesa/src/util/tests/hash_table/insert_many.c | 75 ++ lib/mesa/src/util/tests/hash_table/null_destroy.c | 40 + lib/mesa/src/util/tests/hash_table/random_entry.c | 91 ++ lib/mesa/src/util/tests/hash_table/remove_null.c | 45 + lib/mesa/src/util/tests/hash_table/replacement.c | 66 + lib/mesa/src/util/texcompress_rgtc_tmp.h | 418 ++++++ lib/mesa/src/util/u_atomic.h | 263 ++++ lib/mesa/src/util/u_atomic_test.c | 162 +++ 40 files changed, 9109 insertions(+) create mode 100644 lib/mesa/src/util/Makefile.am create mode 100644 lib/mesa/src/util/Makefile.in create mode 100644 lib/mesa/src/util/Makefile.sources create mode 100644 lib/mesa/src/util/SConscript create mode 100644 lib/mesa/src/util/bitset.h create mode 100644 lib/mesa/src/util/format_srgb.c create mode 100644 lib/mesa/src/util/format_srgb.h create mode 100644 lib/mesa/src/util/format_srgb.py create mode 100644 lib/mesa/src/util/hash_table.c create mode 100644 lib/mesa/src/util/hash_table.h create mode 100644 lib/mesa/src/util/list.h create mode 100644 lib/mesa/src/util/macros.h create mode 100644 lib/mesa/src/util/ralloc.c create mode 100644 lib/mesa/src/util/ralloc.h create mode 100644 lib/mesa/src/util/register_allocate.c create mode 100644 lib/mesa/src/util/register_allocate.h create mode 100644 lib/mesa/src/util/rgtc.c create mode 100644 lib/mesa/src/util/rgtc.h create mode 100644 lib/mesa/src/util/roundeven_test.c create mode 100644 lib/mesa/src/util/rounding.h create mode 100644 lib/mesa/src/util/set.c create mode 100644 lib/mesa/src/util/set.h create mode 100644 lib/mesa/src/util/simple_list.h create mode 100644 lib/mesa/src/util/strtod.c create mode 100644 lib/mesa/src/util/strtod.h create mode 100644 lib/mesa/src/util/tests/hash_table/Makefile.am create mode 100644 lib/mesa/src/util/tests/hash_table/Makefile.in create mode 100644 lib/mesa/src/util/tests/hash_table/collision.c create mode 100644 lib/mesa/src/util/tests/hash_table/delete_and_lookup.c create mode 100644 lib/mesa/src/util/tests/hash_table/delete_management.c create mode 100644 lib/mesa/src/util/tests/hash_table/destroy_callback.c create mode 100644 lib/mesa/src/util/tests/hash_table/insert_and_lookup.c create mode 100644 lib/mesa/src/util/tests/hash_table/insert_many.c create mode 100644 lib/mesa/src/util/tests/hash_table/null_destroy.c create mode 100644 lib/mesa/src/util/tests/hash_table/random_entry.c create mode 100644 lib/mesa/src/util/tests/hash_table/remove_null.c create mode 100644 lib/mesa/src/util/tests/hash_table/replacement.c create mode 100644 lib/mesa/src/util/texcompress_rgtc_tmp.h create mode 100644 lib/mesa/src/util/u_atomic.h create mode 100644 lib/mesa/src/util/u_atomic_test.c (limited to 'lib/mesa/src/util') diff --git a/lib/mesa/src/util/Makefile.am b/lib/mesa/src/util/Makefile.am new file mode 100644 index 000000000..39568aac1 --- /dev/null +++ b/lib/mesa/src/util/Makefile.am @@ -0,0 +1,58 @@ +# Copyright © 2014 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +SUBDIRS = . tests/hash_table + +include Makefile.sources + +noinst_LTLIBRARIES = libmesautil.la + +AM_CPPFLAGS = \ + -I$(top_srcdir)/include + +libmesautil_la_CPPFLAGS = \ + $(DEFINES) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/mapi \ + -I$(top_srcdir)/src/mesa \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gallium/auxiliary \ + $(VISIBILITY_CFLAGS) \ + $(MSVC2008_COMPAT_CFLAGS) + +libmesautil_la_SOURCES = \ + $(MESA_UTIL_FILES) \ + $(MESA_UTIL_GENERATED_FILES) + +roundeven_test_LDADD = -lm + +check_PROGRAMS = u_atomic_test roundeven_test +TESTS = $(check_PROGRAMS) + +BUILT_SOURCES = $(MESA_UTIL_GENERATED_FILES) +CLEANFILES = $(BUILT_SOURCES) +EXTRA_DIST = format_srgb.py SConscript + +PYTHON_GEN = $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) + +format_srgb.c: format_srgb.py + $(PYTHON_GEN) $(srcdir)/format_srgb.py > $@ diff --git a/lib/mesa/src/util/Makefile.in b/lib/mesa/src/util/Makefile.in new file mode 100644 index 000000000..d9df7e4d8 --- /dev/null +++ b/lib/mesa/src/util/Makefile.in @@ -0,0 +1,1414 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright © 2014 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +check_PROGRAMS = u_atomic_test$(EXEEXT) roundeven_test$(EXEEXT) +subdir = src/util +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_gnu_make.m4 \ + $(top_srcdir)/m4/ax_check_python_mako_module.m4 \ + $(top_srcdir)/m4/ax_gcc_builtin.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_prog_bison.m4 \ + $(top_srcdir)/m4/ax_prog_flex.m4 \ + $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/VERSION $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libmesautil_la_LIBADD = +am__objects_1 = libmesautil_la-hash_table.lo libmesautil_la-ralloc.lo \ + libmesautil_la-register_allocate.lo libmesautil_la-rgtc.lo \ + libmesautil_la-set.lo libmesautil_la-strtod.lo +am__objects_2 = libmesautil_la-format_srgb.lo +am_libmesautil_la_OBJECTS = $(am__objects_1) $(am__objects_2) +libmesautil_la_OBJECTS = $(am_libmesautil_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +roundeven_test_SOURCES = roundeven_test.c +roundeven_test_OBJECTS = roundeven_test.$(OBJEXT) +roundeven_test_DEPENDENCIES = +u_atomic_test_SOURCES = u_atomic_test.c +u_atomic_test_OBJECTS = u_atomic_test.$(OBJEXT) +u_atomic_test_LDADD = $(LDADD) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/bin/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libmesautil_la_SOURCES) roundeven_test.c u_atomic_test.c +DIST_SOURCES = $(libmesautil_la_SOURCES) roundeven_test.c \ + u_atomic_test.c +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + check recheck distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.sources \ + $(top_srcdir)/bin/depcomp $(top_srcdir)/bin/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMDGPU_CFLAGS = @AMDGPU_CFLAGS@ +AMDGPU_LIBS = @AMDGPU_LIBS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BSYMBOLIC = @BSYMBOLIC@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLANG_RESOURCE_DIR = @CLANG_RESOURCE_DIR@ +CLOCK_LIB = @CLOCK_LIB@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +D3D_DRIVER_INSTALL_DIR = @D3D_DRIVER_INSTALL_DIR@ +DEFINES = @DEFINES@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DLOPEN_LIBS = @DLOPEN_LIBS@ +DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ +DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ +DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ +DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ +DRIGL_CFLAGS = @DRIGL_CFLAGS@ +DRIGL_LIBS = @DRIGL_LIBS@ +DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@ +DRI_DRIVER_SEARCH_DIR = @DRI_DRIVER_SEARCH_DIR@ +DRI_LIB_DEPS = @DRI_LIB_DEPS@ +DRI_PC_REQ_PRIV = @DRI_PC_REQ_PRIV@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGL_CFLAGS = @EGL_CFLAGS@ +EGL_CLIENT_APIS = @EGL_CLIENT_APIS@ +EGL_LIB_DEPS = @EGL_LIB_DEPS@ +EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@ +EGREP = @EGREP@ +ELF_LIB = @ELF_LIB@ +EXEEXT = @EXEEXT@ +EXPAT_CFLAGS = @EXPAT_CFLAGS@ +EXPAT_LIBS = @EXPAT_LIBS@ +FGREP = @FGREP@ +FREEDRENO_CFLAGS = @FREEDRENO_CFLAGS@ +FREEDRENO_LIBS = @FREEDRENO_LIBS@ +GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@ +GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@ +GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@ +GC_SECTIONS = @GC_SECTIONS@ +GLESv1_CM_LIB_DEPS = @GLESv1_CM_LIB_DEPS@ +GLESv1_CM_PC_LIB_PRIV = @GLESv1_CM_PC_LIB_PRIV@ +GLESv2_LIB_DEPS = @GLESv2_LIB_DEPS@ +GLESv2_PC_LIB_PRIV = @GLESv2_PC_LIB_PRIV@ +GLPROTO_CFLAGS = @GLPROTO_CFLAGS@ +GLPROTO_LIBS = @GLPROTO_LIBS@ +GLX_TLS = @GLX_TLS@ +GL_LIB = @GL_LIB@ +GL_LIB_DEPS = @GL_LIB_DEPS@ +GL_PC_CFLAGS = @GL_PC_CFLAGS@ +GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@ +GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@ +GREP = @GREP@ +HAVE_XF86VIDMODE = @HAVE_XF86VIDMODE@ +INDENT = @INDENT@ +INDENT_FLAGS = @INDENT_FLAGS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTEL_CFLAGS = @INTEL_CFLAGS@ +INTEL_LIBS = @INTEL_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LD_NO_UNDEFINED = @LD_NO_UNDEFINED@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@ +LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@ +LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ +LIBDRM_LIBS = @LIBDRM_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUDEV_CFLAGS = @LIBUDEV_CFLAGS@ +LIBUDEV_LIBS = @LIBUDEV_LIBS@ +LIB_DIR = @LIB_DIR@ +LIB_EXT = @LIB_EXT@ +LIPO = @LIPO@ +LLVM_BINDIR = @LLVM_BINDIR@ +LLVM_CFLAGS = @LLVM_CFLAGS@ +LLVM_CONFIG = @LLVM_CONFIG@ +LLVM_CPPFLAGS = @LLVM_CPPFLAGS@ +LLVM_CXXFLAGS = @LLVM_CXXFLAGS@ +LLVM_INCLUDEDIR = @LLVM_INCLUDEDIR@ +LLVM_LDFLAGS = @LLVM_LDFLAGS@ +LLVM_LIBDIR = @LLVM_LIBDIR@ +LLVM_LIBS = @LLVM_LIBS@ +LLVM_VERSION = @LLVM_VERSION@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MESA_LLVM = @MESA_LLVM@ +MKDIR_P = @MKDIR_P@ +MSVC2008_COMPAT_CFLAGS = @MSVC2008_COMPAT_CFLAGS@ +MSVC2008_COMPAT_CXXFLAGS = @MSVC2008_COMPAT_CXXFLAGS@ +MSVC2013_COMPAT_CFLAGS = @MSVC2013_COMPAT_CFLAGS@ +MSVC2013_COMPAT_CXXFLAGS = @MSVC2013_COMPAT_CXXFLAGS@ +NINE_MAJOR = @NINE_MAJOR@ +NINE_MINOR = @NINE_MINOR@ +NINE_TINY = @NINE_TINY@ +NINE_VERSION = @NINE_VERSION@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NOUVEAU_CFLAGS = @NOUVEAU_CFLAGS@ +NOUVEAU_LIBS = @NOUVEAU_LIBS@ +NVVIEUX_CFLAGS = @NVVIEUX_CFLAGS@ +NVVIEUX_LIBS = @NVVIEUX_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OMX_CFLAGS = @OMX_CFLAGS@ +OMX_LIBS = @OMX_LIBS@ +OMX_LIB_INSTALL_DIR = @OMX_LIB_INSTALL_DIR@ +OPENCL_LIBNAME = @OPENCL_LIBNAME@ +OPENCL_VERSION = @OPENCL_VERSION@ +OSMESA_LIB = @OSMESA_LIB@ +OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@ +OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@ +OSMESA_PC_REQ = @OSMESA_PC_REQ@ +OSMESA_VERSION = @OSMESA_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +PRESENTPROTO_CFLAGS = @PRESENTPROTO_CFLAGS@ +PRESENTPROTO_LIBS = @PRESENTPROTO_LIBS@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +PYTHON2 = @PYTHON2@ +RADEON_CFLAGS = @RADEON_CFLAGS@ +RADEON_LIBS = @RADEON_LIBS@ +RANLIB = @RANLIB@ +RM = @RM@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SSE41_CFLAGS = @SSE41_CFLAGS@ +STRIP = @STRIP@ +VA_CFLAGS = @VA_CFLAGS@ +VA_LIBS = @VA_LIBS@ +VA_LIB_INSTALL_DIR = @VA_LIB_INSTALL_DIR@ +VA_MAJOR = @VA_MAJOR@ +VA_MINOR = @VA_MINOR@ +VDPAU_CFLAGS = @VDPAU_CFLAGS@ +VDPAU_LIBS = @VDPAU_LIBS@ +VDPAU_LIB_INSTALL_DIR = @VDPAU_LIB_INSTALL_DIR@ +VDPAU_MAJOR = @VDPAU_MAJOR@ +VDPAU_MINOR = @VDPAU_MINOR@ +VERSION = @VERSION@ +VG_LIB_DEPS = @VG_LIB_DEPS@ +VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ +VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@ +VL_CFLAGS = @VL_CFLAGS@ +VL_LIBS = @VL_LIBS@ +WAYLAND_CFLAGS = @WAYLAND_CFLAGS@ +WAYLAND_LIBS = @WAYLAND_LIBS@ +WAYLAND_SCANNER = @WAYLAND_SCANNER@ +WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ +WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ +X11_INCLUDES = @X11_INCLUDES@ +XA_MAJOR = @XA_MAJOR@ +XA_MINOR = @XA_MINOR@ +XA_TINY = @XA_TINY@ +XA_VERSION = @XA_VERSION@ +XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@ +XCB_DRI2_LIBS = @XCB_DRI2_LIBS@ +XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@ +XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@ +XLIBGL_CFLAGS = @XLIBGL_CFLAGS@ +XLIBGL_LIBS = @XLIBGL_LIBS@ +XVMC_CFLAGS = @XVMC_CFLAGS@ +XVMC_LIBS = @XVMC_LIBS@ +XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@ +XVMC_MAJOR = @XVMC_MAJOR@ +XVMC_MINOR = @XVMC_MINOR@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acv_mako_found = @acv_mako_found@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +ifGNUmake = @ifGNUmake@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = . tests/hash_table +MESA_UTIL_FILES := \ + bitset.h \ + format_srgb.h \ + hash_table.c \ + hash_table.h \ + list.h \ + macros.h \ + ralloc.c \ + ralloc.h \ + register_allocate.c \ + register_allocate.h \ + rgtc.c \ + rgtc.h \ + rounding.h \ + set.c \ + set.h \ + simple_list.h \ + strtod.c \ + strtod.h \ + texcompress_rgtc_tmp.h \ + u_atomic.h + +MESA_UTIL_GENERATED_FILES = \ + format_srgb.c + +noinst_LTLIBRARIES = libmesautil.la +AM_CPPFLAGS = \ + -I$(top_srcdir)/include + +libmesautil_la_CPPFLAGS = \ + $(DEFINES) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/mapi \ + -I$(top_srcdir)/src/mesa \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gallium/auxiliary \ + $(VISIBILITY_CFLAGS) \ + $(MSVC2008_COMPAT_CFLAGS) + +libmesautil_la_SOURCES = \ + $(MESA_UTIL_FILES) \ + $(MESA_UTIL_GENERATED_FILES) + +roundeven_test_LDADD = -lm +TESTS = $(check_PROGRAMS) +BUILT_SOURCES = $(MESA_UTIL_GENERATED_FILES) +CLEANFILES = $(BUILT_SOURCES) +EXTRA_DIST = format_srgb.py SConscript +PYTHON_GEN = $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/Makefile.sources $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/util/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/util/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; +$(srcdir)/Makefile.sources $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libmesautil.la: $(libmesautil_la_OBJECTS) $(libmesautil_la_DEPENDENCIES) $(EXTRA_libmesautil_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libmesautil_la_OBJECTS) $(libmesautil_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +roundeven_test$(EXEEXT): $(roundeven_test_OBJECTS) $(roundeven_test_DEPENDENCIES) $(EXTRA_roundeven_test_DEPENDENCIES) + @rm -f roundeven_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(roundeven_test_OBJECTS) $(roundeven_test_LDADD) $(LIBS) + +u_atomic_test$(EXEEXT): $(u_atomic_test_OBJECTS) $(u_atomic_test_DEPENDENCIES) $(EXTRA_u_atomic_test_DEPENDENCIES) + @rm -f u_atomic_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(u_atomic_test_OBJECTS) $(u_atomic_test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmesautil_la-format_srgb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmesautil_la-hash_table.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmesautil_la-ralloc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmesautil_la-register_allocate.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmesautil_la-rgtc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmesautil_la-set.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmesautil_la-strtod.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/roundeven_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_atomic_test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libmesautil_la-hash_table.lo: hash_table.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmesautil_la-hash_table.lo -MD -MP -MF $(DEPDIR)/libmesautil_la-hash_table.Tpo -c -o libmesautil_la-hash_table.lo `test -f 'hash_table.c' || echo '$(srcdir)/'`hash_table.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmesautil_la-hash_table.Tpo $(DEPDIR)/libmesautil_la-hash_table.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash_table.c' object='libmesautil_la-hash_table.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmesautil_la-hash_table.lo `test -f 'hash_table.c' || echo '$(srcdir)/'`hash_table.c + +libmesautil_la-ralloc.lo: ralloc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmesautil_la-ralloc.lo -MD -MP -MF $(DEPDIR)/libmesautil_la-ralloc.Tpo -c -o libmesautil_la-ralloc.lo `test -f 'ralloc.c' || echo '$(srcdir)/'`ralloc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmesautil_la-ralloc.Tpo $(DEPDIR)/libmesautil_la-ralloc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ralloc.c' object='libmesautil_la-ralloc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmesautil_la-ralloc.lo `test -f 'ralloc.c' || echo '$(srcdir)/'`ralloc.c + +libmesautil_la-register_allocate.lo: register_allocate.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmesautil_la-register_allocate.lo -MD -MP -MF $(DEPDIR)/libmesautil_la-register_allocate.Tpo -c -o libmesautil_la-register_allocate.lo `test -f 'register_allocate.c' || echo '$(srcdir)/'`register_allocate.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmesautil_la-register_allocate.Tpo $(DEPDIR)/libmesautil_la-register_allocate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='register_allocate.c' object='libmesautil_la-register_allocate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmesautil_la-register_allocate.lo `test -f 'register_allocate.c' || echo '$(srcdir)/'`register_allocate.c + +libmesautil_la-rgtc.lo: rgtc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmesautil_la-rgtc.lo -MD -MP -MF $(DEPDIR)/libmesautil_la-rgtc.Tpo -c -o libmesautil_la-rgtc.lo `test -f 'rgtc.c' || echo '$(srcdir)/'`rgtc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmesautil_la-rgtc.Tpo $(DEPDIR)/libmesautil_la-rgtc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rgtc.c' object='libmesautil_la-rgtc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmesautil_la-rgtc.lo `test -f 'rgtc.c' || echo '$(srcdir)/'`rgtc.c + +libmesautil_la-set.lo: set.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmesautil_la-set.lo -MD -MP -MF $(DEPDIR)/libmesautil_la-set.Tpo -c -o libmesautil_la-set.lo `test -f 'set.c' || echo '$(srcdir)/'`set.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmesautil_la-set.Tpo $(DEPDIR)/libmesautil_la-set.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='set.c' object='libmesautil_la-set.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmesautil_la-set.lo `test -f 'set.c' || echo '$(srcdir)/'`set.c + +libmesautil_la-strtod.lo: strtod.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmesautil_la-strtod.lo -MD -MP -MF $(DEPDIR)/libmesautil_la-strtod.Tpo -c -o libmesautil_la-strtod.lo `test -f 'strtod.c' || echo '$(srcdir)/'`strtod.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmesautil_la-strtod.Tpo $(DEPDIR)/libmesautil_la-strtod.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strtod.c' object='libmesautil_la-strtod.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmesautil_la-strtod.lo `test -f 'strtod.c' || echo '$(srcdir)/'`strtod.c + +libmesautil_la-format_srgb.lo: format_srgb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmesautil_la-format_srgb.lo -MD -MP -MF $(DEPDIR)/libmesautil_la-format_srgb.Tpo -c -o libmesautil_la-format_srgb.lo `test -f 'format_srgb.c' || echo '$(srcdir)/'`format_srgb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmesautil_la-format_srgb.Tpo $(DEPDIR)/libmesautil_la-format_srgb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='format_srgb.c' object='libmesautil_la-format_srgb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesautil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmesautil_la-format_srgb.lo `test -f 'format_srgb.c' || echo '$(srcdir)/'`format_srgb.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +u_atomic_test.log: u_atomic_test$(EXEEXT) + @p='u_atomic_test$(EXEEXT)'; \ + b='u_atomic_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +roundeven_test.log: roundeven_test$(EXEEXT) + @p='roundeven_test$(EXEEXT)'; \ + b='roundeven_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(LTLIBRARIES) +installdirs: installdirs-recursive +installdirs-am: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) all check check-am install install-am \ + install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-TESTS check-am clean clean-checkPROGRAMS clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +format_srgb.c: format_srgb.py + $(PYTHON_GEN) $(srcdir)/format_srgb.py > $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/mesa/src/util/Makefile.sources b/lib/mesa/src/util/Makefile.sources new file mode 100644 index 000000000..1f5386a00 --- /dev/null +++ b/lib/mesa/src/util/Makefile.sources @@ -0,0 +1,24 @@ +MESA_UTIL_FILES := \ + bitset.h \ + format_srgb.h \ + hash_table.c \ + hash_table.h \ + list.h \ + macros.h \ + ralloc.c \ + ralloc.h \ + register_allocate.c \ + register_allocate.h \ + rgtc.c \ + rgtc.h \ + rounding.h \ + set.c \ + set.h \ + simple_list.h \ + strtod.c \ + strtod.h \ + texcompress_rgtc_tmp.h \ + u_atomic.h + +MESA_UTIL_GENERATED_FILES = \ + format_srgb.c diff --git a/lib/mesa/src/util/SConscript b/lib/mesa/src/util/SConscript new file mode 100644 index 000000000..bd8fb1727 --- /dev/null +++ b/lib/mesa/src/util/SConscript @@ -0,0 +1,58 @@ +import common + +Import('*') + +from sys import executable as python_cmd + +env = env.Clone() + +env.MSVC2008Compat() + +env.Prepend(CPPPATH = [ + '#include', + '#src', + '#src/mapi', + '#src/mesa', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/util', +]) + +env.CodeGenerate( + target = 'format_srgb.c', + script = 'format_srgb.py', + source = [], + command = python_cmd + ' $SCRIPT > $TARGET' +) + +# parse Makefile.sources +source_lists = env.ParseSourceList('Makefile.sources') + +mesautil_sources = ( + source_lists['MESA_UTIL_FILES'] + + source_lists['MESA_UTIL_GENERATED_FILES'] +) + +mesautil = env.ConvenienceLibrary( + target = 'mesautil', + source = mesautil_sources, +) + +env.Alias('mesautil', mesautil) +Export('mesautil') + + +# http://www.scons.org/wiki/UnitTests +u_atomic_test = env.Program( + target = 'u_atomic_test', + source = ['u_atomic_test.c'], +) +alias = env.Alias("u_atomic_test", u_atomic_test, u_atomic_test[0].abspath) +AlwaysBuild(alias) + +roundeven_test = env.Program( + target = 'roundeven_test', + source = ['roundeven_test.c'], +) +alias = env.Alias("roundeven_test", roundeven_test, roundeven_test[0].abspath) +AlwaysBuild(alias) diff --git a/lib/mesa/src/util/bitset.h b/lib/mesa/src/util/bitset.h new file mode 100644 index 000000000..c45281941 --- /dev/null +++ b/lib/mesa/src/util/bitset.h @@ -0,0 +1,135 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file bitset.h + * \brief Bitset of arbitrary size definitions. + * \author Michal Krol + */ + +#ifndef BITSET_H +#define BITSET_H + +#include "util/u_math.h" + +/**************************************************************************** + * generic bitset implementation + */ + +#define BITSET_WORD unsigned int +#define BITSET_WORDBITS (sizeof (BITSET_WORD) * 8) + +/* bitset declarations + */ +#define BITSET_WORDS(bits) (((bits) + BITSET_WORDBITS - 1) / BITSET_WORDBITS) +#define BITSET_DECLARE(name, bits) BITSET_WORD name[BITSET_WORDS(bits)] + +/* bitset operations + */ +#define BITSET_COPY(x, y) memcpy( (x), (y), sizeof (x) ) +#define BITSET_EQUAL(x, y) (memcmp( (x), (y), sizeof (x) ) == 0) +#define BITSET_ZERO(x) memset( (x), 0, sizeof (x) ) +#define BITSET_ONES(x) memset( (x), 0xff, sizeof (x) ) + +#define BITSET_BITWORD(b) ((b) / BITSET_WORDBITS) +#define BITSET_BIT(b) (1 << ((b) % BITSET_WORDBITS)) + +/* single bit operations + */ +#define BITSET_TEST(x, b) ((x)[BITSET_BITWORD(b)] & BITSET_BIT(b)) +#define BITSET_SET(x, b) ((x)[BITSET_BITWORD(b)] |= BITSET_BIT(b)) +#define BITSET_CLEAR(x, b) ((x)[BITSET_BITWORD(b)] &= ~BITSET_BIT(b)) + +#define BITSET_MASK(b) ((b) == BITSET_WORDBITS ? ~0 : BITSET_BIT(b) - 1) +#define BITSET_RANGE(b, e) (BITSET_MASK((e) + 1) & ~BITSET_MASK(b)) + +/* bit range operations + */ +#define BITSET_TEST_RANGE(x, b, e) \ + (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \ + ((x)[BITSET_BITWORD(b)] & BITSET_RANGE(b, e)) : \ + (assert (!"BITSET_TEST_RANGE: bit range crosses word boundary"), 0)) +#define BITSET_SET_RANGE(x, b, e) \ + (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \ + ((x)[BITSET_BITWORD(b)] |= BITSET_RANGE(b, e)) : \ + (assert (!"BITSET_SET_RANGE: bit range crosses word boundary"), 0)) +#define BITSET_CLEAR_RANGE(x, b, e) \ + (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \ + ((x)[BITSET_BITWORD(b)] &= ~BITSET_RANGE(b, e)) : \ + (assert (!"BITSET_CLEAR_RANGE: bit range crosses word boundary"), 0)) + +/* Get first bit set in a bitset. + */ +static inline int +__bitset_ffs(const BITSET_WORD *x, int n) +{ + int i; + + for (i = 0; i < n; i++) { + if (x[i]) + return ffs(x[i]) + BITSET_WORDBITS * i; + } + + return 0; +} + +#define BITSET_FFS(x) __bitset_ffs(x, ARRAY_SIZE(x)) + +static inline unsigned +__bitset_next_set(unsigned i, BITSET_WORD *tmp, + BITSET_WORD *set, unsigned size) +{ + unsigned bit, word; + + /* NOTE: The initial conditions for this function are very specific. At + * the start of the loop, the tmp variable must be set to *set and the + * initial i value set to 0. This way, if there is a bit set in the first + * word, we ignore the i-value and just grab that bit (so 0 is ok, even + * though 0 may be returned). If the first word is 0, then the value of + * `word` will be 0 and we will go on to look at the second word. + */ + word = BITSET_BITWORD(i); + while (*tmp == 0) { + word++; + + if (word >= BITSET_WORDS(size)) + return size; + + *tmp = set[word]; + } + + /* Find the next set bit in the non-zero word */ + bit = ffs(*tmp) - 1; + + /* Unset the bit */ + *tmp &= ~(1ull << bit); + + return word * BITSET_WORDBITS + bit; +} + +#define BITSET_FOREACH_SET(__i, __tmp, __set, __size) \ + for (__tmp = *(__set), __i = 0; \ + (__i = __bitset_next_set(__i, &__tmp, __set, __size)) < __size;) + +#endif diff --git a/lib/mesa/src/util/format_srgb.c b/lib/mesa/src/util/format_srgb.c new file mode 100644 index 000000000..a72588082 --- /dev/null +++ b/lib/mesa/src/util/format_srgb.c @@ -0,0 +1,178 @@ +/* This file is autogenerated by u_format_srgb.py. Do not edit directly. */ + +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * SRGB translation. + * + * @author Brian Paul + * @author Michal Krol + * @author Jose Fonseca + */ + +#include "format_srgb.h" + +const float +util_format_srgb_8unorm_to_linear_float_table[256] = { + 0.0000000e+00, 3.0352698e-04, 6.0705397e-04, 9.1058095e-04, + 1.2141079e-03, 1.5176349e-03, 1.8211619e-03, 2.1246889e-03, + 2.4282159e-03, 2.7317429e-03, 3.0352698e-03, 3.3465358e-03, + 3.6765073e-03, 4.0247170e-03, 4.3914420e-03, 4.7769535e-03, + 5.1815167e-03, 5.6053916e-03, 6.0488330e-03, 6.5120908e-03, + 6.9954102e-03, 7.4990320e-03, 8.0231930e-03, 8.5681256e-03, + 9.1340587e-03, 9.7212173e-03, 1.0329823e-02, 1.0960094e-02, + 1.1612245e-02, 1.2286488e-02, 1.2983032e-02, 1.3702083e-02, + 1.4443844e-02, 1.5208514e-02, 1.5996293e-02, 1.6807376e-02, + 1.7641954e-02, 1.8500220e-02, 1.9382361e-02, 2.0288563e-02, + 2.1219010e-02, 2.2173885e-02, 2.3153366e-02, 2.4157632e-02, + 2.5186860e-02, 2.6241222e-02, 2.7320892e-02, 2.8426040e-02, + 2.9556834e-02, 3.0713444e-02, 3.1896033e-02, 3.3104767e-02, + 3.4339807e-02, 3.5601315e-02, 3.6889450e-02, 3.8204372e-02, + 3.9546235e-02, 4.0915197e-02, 4.2311411e-02, 4.3735029e-02, + 4.5186204e-02, 4.6665086e-02, 4.8171824e-02, 4.9706566e-02, + 5.1269458e-02, 5.2860647e-02, 5.4480276e-02, 5.6128490e-02, + 5.7805430e-02, 5.9511238e-02, 6.1246054e-02, 6.3010018e-02, + 6.4803267e-02, 6.6625939e-02, 6.8478170e-02, 7.0360096e-02, + 7.2271851e-02, 7.4213568e-02, 7.6185381e-02, 7.8187422e-02, + 8.0219820e-02, 8.2282707e-02, 8.4376212e-02, 8.6500462e-02, + 8.8655586e-02, 9.0841711e-02, 9.3058963e-02, 9.5307467e-02, + 9.7587347e-02, 9.9898728e-02, 1.0224173e-01, 1.0461648e-01, + 1.0702310e-01, 1.0946171e-01, 1.1193243e-01, 1.1443537e-01, + 1.1697067e-01, 1.1953843e-01, 1.2213877e-01, 1.2477182e-01, + 1.2743768e-01, 1.3013648e-01, 1.3286832e-01, 1.3563333e-01, + 1.3843162e-01, 1.4126329e-01, 1.4412847e-01, 1.4702727e-01, + 1.4995979e-01, 1.5292615e-01, 1.5592646e-01, 1.5896084e-01, + 1.6202938e-01, 1.6513219e-01, 1.6826940e-01, 1.7144110e-01, + 1.7464740e-01, 1.7788842e-01, 1.8116424e-01, 1.8447499e-01, + 1.8782077e-01, 1.9120168e-01, 1.9461783e-01, 1.9806932e-01, + 2.0155625e-01, 2.0507874e-01, 2.0863687e-01, 2.1223076e-01, + 2.1586050e-01, 2.1952620e-01, 2.2322796e-01, 2.2696587e-01, + 2.3074005e-01, 2.3455058e-01, 2.3839757e-01, 2.4228112e-01, + 2.4620133e-01, 2.5015828e-01, 2.5415209e-01, 2.5818285e-01, + 2.6225066e-01, 2.6635560e-01, 2.7049779e-01, 2.7467731e-01, + 2.7889426e-01, 2.8314874e-01, 2.8744084e-01, 2.9177065e-01, + 2.9613827e-01, 3.0054379e-01, 3.0498731e-01, 3.0946892e-01, + 3.1398871e-01, 3.1854678e-01, 3.2314321e-01, 3.2777810e-01, + 3.3245154e-01, 3.3716362e-01, 3.4191442e-01, 3.4670406e-01, + 3.5153260e-01, 3.5640014e-01, 3.6130678e-01, 3.6625260e-01, + 3.7123768e-01, 3.7626212e-01, 3.8132601e-01, 3.8642943e-01, + 3.9157248e-01, 3.9675523e-01, 4.0197778e-01, 4.0724021e-01, + 4.1254261e-01, 4.1788507e-01, 4.2326767e-01, 4.2869050e-01, + 4.3415364e-01, 4.3965717e-01, 4.4520119e-01, 4.5078578e-01, + 4.5641102e-01, 4.6207700e-01, 4.6778380e-01, 4.7353150e-01, + 4.7932018e-01, 4.8514994e-01, 4.9102085e-01, 4.9693300e-01, + 5.0288646e-01, 5.0888132e-01, 5.1491767e-01, 5.2099557e-01, + 5.2711513e-01, 5.3327640e-01, 5.3947949e-01, 5.4572446e-01, + 5.5201140e-01, 5.5834039e-01, 5.6471151e-01, 5.7112483e-01, + 5.7758044e-01, 5.8407842e-01, 5.9061884e-01, 5.9720179e-01, + 6.0382734e-01, 6.1049557e-01, 6.1720656e-01, 6.2396039e-01, + 6.3075714e-01, 6.3759687e-01, 6.4447968e-01, 6.5140564e-01, + 6.5837482e-01, 6.6538730e-01, 6.7244316e-01, 6.7954247e-01, + 6.8668531e-01, 6.9387176e-01, 7.0110189e-01, 7.0837578e-01, + 7.1569350e-01, 7.2305513e-01, 7.3046074e-01, 7.3791041e-01, + 7.4540421e-01, 7.5294222e-01, 7.6052450e-01, 7.6815115e-01, + 7.7582222e-01, 7.8353779e-01, 7.9129794e-01, 7.9910274e-01, + 8.0695226e-01, 8.1484657e-01, 8.2278575e-01, 8.3076988e-01, + 8.3879901e-01, 8.4687323e-01, 8.5499261e-01, 8.6315721e-01, + 8.7136712e-01, 8.7962240e-01, 8.8792312e-01, 8.9626935e-01, + 9.0466117e-01, 9.1309865e-01, 9.2158186e-01, 9.3011086e-01, + 9.3868573e-01, 9.4730654e-01, 9.5597335e-01, 9.6468625e-01, + 9.7344529e-01, 9.8225055e-01, 9.9110210e-01, 1.0000000e+00, +}; + +const uint8_t +util_format_srgb_to_linear_8unorm_table[256] = { + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, + 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, + 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 20, + 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29, + 30, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 37, 38, 39, 40, 41, + 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, + 90, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 108, 109, + 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, 125, 127, 128, 130, 131, 133, + 134, 136, 138, 139, 141, 142, 144, 146, 147, 149, 151, 152, 154, 156, 157, 159, + 161, 163, 164, 166, 168, 170, 171, 173, 175, 177, 179, 181, 183, 184, 186, 188, + 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, + 222, 224, 226, 229, 231, 233, 235, 237, 239, 242, 244, 246, 248, 250, 253, 255, +}; + +const uint8_t +util_format_linear_to_srgb_8unorm_table[256] = { + 0, 13, 22, 28, 34, 38, 42, 46, 50, 53, 56, 59, 61, 64, 66, 69, + 71, 73, 75, 77, 79, 81, 83, 85, 86, 88, 90, 92, 93, 95, 96, 98, + 99, 101, 102, 104, 105, 106, 108, 109, 110, 112, 113, 114, 115, 117, 118, 119, + 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 151, + 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164, + 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 175, 176, + 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 187, + 188, 189, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197, + 198, 199, 199, 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207, + 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216, + 216, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224, + 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, + 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, + 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248, + 248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255, +}; + +const unsigned +util_format_linear_to_srgb_helper_table[104] = { + 0x0073000d, 0x007a000d, 0x0080000d, 0x0087000d, + 0x008d000d, 0x0094000d, 0x009a000d, 0x00a1000d, + 0x00a7001a, 0x00b4001a, 0x00c1001a, 0x00ce001a, + 0x00da001a, 0x00e7001a, 0x00f4001a, 0x0101001a, + 0x010e0033, 0x01280033, 0x01410033, 0x015b0033, + 0x01750033, 0x018f0033, 0x01a80033, 0x01c20033, + 0x01dc0067, 0x020f0067, 0x02430067, 0x02760067, + 0x02aa0067, 0x02dd0067, 0x03110067, 0x03440067, + 0x037800ce, 0x03df00ce, 0x044600ce, 0x04ad00ce, + 0x051400ce, 0x057b00c5, 0x05dd00bc, 0x063b00b5, + 0x06970158, 0x07420142, 0x07e30130, 0x087b0120, + 0x090b0112, 0x09940106, 0x0a1700fc, 0x0a9500f2, + 0x0b0f01cb, 0x0bf401ae, 0x0ccb0195, 0x0d950180, + 0x0e56016e, 0x0f0d015e, 0x0fbc0150, 0x10630143, + 0x11070264, 0x1238023e, 0x1357021d, 0x14660201, + 0x156601e9, 0x165a01d3, 0x174401c0, 0x182401af, + 0x18fe0331, 0x1a9602fe, 0x1c1502d2, 0x1d7e02ad, + 0x1ed4028d, 0x201a0270, 0x21520256, 0x227d0240, + 0x239f0443, 0x25c003fe, 0x27bf03c4, 0x29a10392, + 0x2b6a0367, 0x2d1d0341, 0x2ebe031f, 0x304d0300, + 0x31d105b0, 0x34a80555, 0x37520507, 0x39d504c5, + 0x3c37048b, 0x3e7c0458, 0x40a8042a, 0x42bd0401, + 0x44c20798, 0x488e071e, 0x4c1c06b6, 0x4f76065d, + 0x52a50610, 0x55ac05cc, 0x5892058f, 0x5b590559, + 0x5e0c0a23, 0x631c0980, 0x67db08f6, 0x6c55087f, + 0x70940818, 0x74a007bd, 0x787d076c, 0x7c330723, +}; + diff --git a/lib/mesa/src/util/format_srgb.h b/lib/mesa/src/util/format_srgb.h new file mode 100644 index 000000000..4a8d73f12 --- /dev/null +++ b/lib/mesa/src/util/format_srgb.h @@ -0,0 +1,149 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + +/** + * @file + * SRGB translation. + * + * @author Brian Paul + * @author Michal Krol + * @author Jose Fonseca + */ + +#ifndef U_FORMAT_SRGB_H_ +#define U_FORMAT_SRGB_H_ + +#include +#include +#include "c99_compat.h" + +extern const float +util_format_srgb_8unorm_to_linear_float_table[256]; + +extern const uint8_t +util_format_srgb_to_linear_8unorm_table[256]; + +extern const uint8_t +util_format_linear_to_srgb_8unorm_table[256]; + +extern const unsigned +util_format_linear_to_srgb_helper_table[104]; + + +static inline float +util_format_linear_to_srgb_float(float cl) +{ + if (cl < 0.0f) + return 0.0f; + else if (cl < 0.0031308f) + return 12.92f * cl; + else if (cl < 1.0f) + return 1.055f * powf(cl, 0.41666f) - 0.055f; + else + return 1.0f; +} + + +/** + * Convert a unclamped linear float to srgb value in the [0,255]. + */ +static inline uint8_t +util_format_linear_float_to_srgb_8unorm(float x) +{ + /* + * This is taken from https://gist.github.com/rygorous/2203834 + * Use LUT and do linear interpolation. + */ + union { + uint32_t ui; + float f; + } almostone, minval, f; + unsigned tab, bias, scale, t; + + almostone.ui = 0x3f7fffff; + minval.ui = (127-13) << 23; + + /* + * Clamp to [2^(-13), 1-eps]; these two values map to 0 and 1, respectively. + * The tests are carefully written so that NaNs map to 0, same as in the + * reference implementation. + */ + if (!(x > minval.f)) + x = minval.f; + if (x > almostone.f) + x = almostone.f; + + /* Do the table lookup and unpack bias, scale */ + f.f = x; + tab = util_format_linear_to_srgb_helper_table[(f.ui - minval.ui) >> 20]; + bias = (tab >> 16) << 9; + scale = tab & 0xffff; + + /* Grab next-highest mantissa bits and perform linear interpolation */ + t = (f.ui >> 12) & 0xff; + return (uint8_t) ((bias + scale*t) >> 16); +} + + +/** + * Convert an 8-bit sRGB value from non-linear space to a + * linear RGB value in [0, 1]. + * Implemented with a 256-entry lookup table. + */ +static inline float +util_format_srgb_8unorm_to_linear_float(uint8_t x) +{ + return util_format_srgb_8unorm_to_linear_float_table[x]; +} + + +/* + * XXX These 2 functions probably don't make a lot of sense (but lots + * of potential callers which most likely all don't make sense neither) + */ + +/** + * Convert a 8bit normalized value from linear to srgb. + */ +static inline uint8_t +util_format_linear_to_srgb_8unorm(uint8_t x) +{ + return util_format_linear_to_srgb_8unorm_table[x]; +} + + +/** + * Convert a 8bit normalized value from srgb to linear. + */ +static inline uint8_t +util_format_srgb_to_linear_8unorm(uint8_t x) +{ + return util_format_srgb_to_linear_8unorm_table[x]; +} + + +#endif /* U_FORMAT_SRGB_H_ */ diff --git a/lib/mesa/src/util/format_srgb.py b/lib/mesa/src/util/format_srgb.py new file mode 100644 index 000000000..d5cbcf764 --- /dev/null +++ b/lib/mesa/src/util/format_srgb.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python + +CopyRight = ''' +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * SRGB translation. + * + * @author Brian Paul + * @author Michal Krol + * @author Jose Fonseca + */ +''' + + +import math +import struct + + +def srgb_to_linear(x): + if x <= 0.04045: + return x / 12.92 + else: + return math.pow((x + 0.055) / 1.055, 2.4) + + +def linear_to_srgb(x): + if x >= 0.0031308: + return 1.055 * math.pow(x, 0.41666666) - 0.055 + else: + return 12.92 * x + + +def generate_srgb_tables(): + print 'const float' + print 'util_format_srgb_8unorm_to_linear_float_table[256] = {' + for j in range(0, 256, 4): + print ' ', + for i in range(j, j + 4): + print '%.7e,' % (srgb_to_linear(i / 255.0),), + print + print '};' + print + print 'const uint8_t' + print 'util_format_srgb_to_linear_8unorm_table[256] = {' + for j in range(0, 256, 16): + print ' ', + for i in range(j, j + 16): + print '%3u,' % (int(srgb_to_linear(i / 255.0) * 255.0 + 0.5),), + print + print '};' + print + print 'const uint8_t' + print 'util_format_linear_to_srgb_8unorm_table[256] = {' + for j in range(0, 256, 16): + print ' ', + for i in range(j, j + 16): + print '%3u,' % (int(linear_to_srgb(i / 255.0) * 255.0 + 0.5),), + print + print '};' + print + +# calculate the table interpolation values used in float linear to unorm8 srgb + numexp = 13 + mantissa_msb = 3 +# stepshift is just used to only use every x-th float to make things faster, +# 5 is largest value which still gives exact same table as 0 + stepshift = 5 + nbuckets = numexp << mantissa_msb + bucketsize = (1 << (23 - mantissa_msb)) >> stepshift + mantshift = 12 + valtable = [] + sum_aa = float(bucketsize) + sum_ab = 0.0 + sum_bb = 0.0 + for i in range(0, bucketsize): + j = (i << stepshift) >> mantshift + sum_ab += j + sum_bb += j*j + inv_det = 1.0 / (sum_aa * sum_bb - sum_ab * sum_ab) + + for bucket in range(0, nbuckets): + start = ((127 - numexp) << 23) + bucket*(bucketsize << stepshift) + sum_a = 0.0 + sum_b = 0.0 + + for i in range(0, bucketsize): + j = (i << stepshift) >> mantshift + fint = start + (i << stepshift) + ffloat = struct.unpack('f', struct.pack('I', fint))[0] + val = linear_to_srgb(ffloat) * 255.0 + 0.5 + sum_a += val + sum_b += j*val + + solved_a = inv_det * (sum_bb*sum_a - sum_ab*sum_b) + solved_b = inv_det * (sum_aa*sum_b - sum_ab*sum_a) + + scaled_a = solved_a * 65536.0 / 512.0 + scaled_b = solved_b * 65536.0 + + int_a = int(scaled_a + 0.5) + int_b = int(scaled_b + 0.5) + + valtable.append((int_a << 16) + int_b) + + print 'const unsigned' + print 'util_format_linear_to_srgb_helper_table[104] = {' + + for j in range(0, nbuckets, 4): + print ' ', + for i in range(j, j + 4): + print '0x%08x,' % (valtable[i],), + print + print '};' + print + +def main(): + print '/* This file is autogenerated by u_format_srgb.py. Do not edit directly. */' + print + # This will print the copyright message on the top of this file + print CopyRight.strip() + print + print '#include "format_srgb.h"' + print + generate_srgb_tables() + + +if __name__ == '__main__': + main() diff --git a/lib/mesa/src/util/hash_table.c b/lib/mesa/src/util/hash_table.c new file mode 100644 index 000000000..3247593c1 --- /dev/null +++ b/lib/mesa/src/util/hash_table.c @@ -0,0 +1,475 @@ +/* + * Copyright © 2009,2012 Intel Corporation + * Copyright © 1988-2004 Keith Packard and Bart Massey. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors + * or their institutions shall not be used in advertising or + * otherwise to promote the sale, use or other dealings in this + * Software without prior written authorization from the + * authors. + * + * Authors: + * Eric Anholt + * Keith Packard + */ + +/** + * Implements an open-addressing, linear-reprobing hash table. + * + * For more information, see: + * + * http://cgit.freedesktop.org/~anholt/hash_table/tree/README + */ + +#include +#include +#include + +#include "hash_table.h" +#include "ralloc.h" +#include "macros.h" + +static const uint32_t deleted_key_value; + +/** + * From Knuth -- a good choice for hash/rehash values is p, p-2 where + * p and p-2 are both prime. These tables are sized to have an extra 10% + * free to avoid exponential performance degradation as the hash table fills + */ +static const struct { + uint32_t max_entries, size, rehash; +} hash_sizes[] = { + { 2, 5, 3 }, + { 4, 7, 5 }, + { 8, 13, 11 }, + { 16, 19, 17 }, + { 32, 43, 41 }, + { 64, 73, 71 }, + { 128, 151, 149 }, + { 256, 283, 281 }, + { 512, 571, 569 }, + { 1024, 1153, 1151 }, + { 2048, 2269, 2267 }, + { 4096, 4519, 4517 }, + { 8192, 9013, 9011 }, + { 16384, 18043, 18041 }, + { 32768, 36109, 36107 }, + { 65536, 72091, 72089 }, + { 131072, 144409, 144407 }, + { 262144, 288361, 288359 }, + { 524288, 576883, 576881 }, + { 1048576, 1153459, 1153457 }, + { 2097152, 2307163, 2307161 }, + { 4194304, 4613893, 4613891 }, + { 8388608, 9227641, 9227639 }, + { 16777216, 18455029, 18455027 }, + { 33554432, 36911011, 36911009 }, + { 67108864, 73819861, 73819859 }, + { 134217728, 147639589, 147639587 }, + { 268435456, 295279081, 295279079 }, + { 536870912, 590559793, 590559791 }, + { 1073741824, 1181116273, 1181116271}, + { 2147483648ul, 2362232233ul, 2362232231ul} +}; + +static int +entry_is_free(const struct hash_entry *entry) +{ + return entry->key == NULL; +} + +static int +entry_is_deleted(const struct hash_table *ht, struct hash_entry *entry) +{ + return entry->key == ht->deleted_key; +} + +static int +entry_is_present(const struct hash_table *ht, struct hash_entry *entry) +{ + return entry->key != NULL && entry->key != ht->deleted_key; +} + +struct hash_table * +_mesa_hash_table_create(void *mem_ctx, + uint32_t (*key_hash_function)(const void *key), + bool (*key_equals_function)(const void *a, + const void *b)) +{ + struct hash_table *ht; + + ht = ralloc(mem_ctx, struct hash_table); + if (ht == NULL) + return NULL; + + ht->size_index = 0; + ht->size = hash_sizes[ht->size_index].size; + ht->rehash = hash_sizes[ht->size_index].rehash; + ht->max_entries = hash_sizes[ht->size_index].max_entries; + ht->key_hash_function = key_hash_function; + ht->key_equals_function = key_equals_function; + ht->table = rzalloc_array(ht, struct hash_entry, ht->size); + ht->entries = 0; + ht->deleted_entries = 0; + ht->deleted_key = &deleted_key_value; + + if (ht->table == NULL) { + ralloc_free(ht); + return NULL; + } + + return ht; +} + +/** + * Frees the given hash table. + * + * If delete_function is passed, it gets called on each entry present before + * freeing. + */ +void +_mesa_hash_table_destroy(struct hash_table *ht, + void (*delete_function)(struct hash_entry *entry)) +{ + if (!ht) + return; + + if (delete_function) { + struct hash_entry *entry; + + hash_table_foreach(ht, entry) { + delete_function(entry); + } + } + ralloc_free(ht); +} + +/** Sets the value of the key pointer used for deleted entries in the table. + * + * The assumption is that usually keys are actual pointers, so we use a + * default value of a pointer to an arbitrary piece of storage in the library. + * But in some cases a consumer wants to store some other sort of value in the + * table, like a uint32_t, in which case that pointer may conflict with one of + * their valid keys. This lets that user select a safe value. + * + * This must be called before any keys are actually deleted from the table. + */ +void +_mesa_hash_table_set_deleted_key(struct hash_table *ht, const void *deleted_key) +{ + ht->deleted_key = deleted_key; +} + +static struct hash_entry * +hash_table_search(struct hash_table *ht, uint32_t hash, const void *key) +{ + uint32_t start_hash_address = hash % ht->size; + uint32_t hash_address = start_hash_address; + + do { + uint32_t double_hash; + + struct hash_entry *entry = ht->table + hash_address; + + if (entry_is_free(entry)) { + return NULL; + } else if (entry_is_present(ht, entry) && entry->hash == hash) { + if (ht->key_equals_function(key, entry->key)) { + return entry; + } + } + + double_hash = 1 + hash % ht->rehash; + + hash_address = (hash_address + double_hash) % ht->size; + } while (hash_address != start_hash_address); + + return NULL; +} + +/** + * Finds a hash table entry with the given key and hash of that key. + * + * Returns NULL if no entry is found. Note that the data pointer may be + * modified by the user. + */ +struct hash_entry * +_mesa_hash_table_search(struct hash_table *ht, const void *key) +{ + assert(ht->key_hash_function); + return hash_table_search(ht, ht->key_hash_function(key), key); +} + +struct hash_entry * +_mesa_hash_table_search_pre_hashed(struct hash_table *ht, uint32_t hash, + const void *key) +{ + assert(ht->key_hash_function == NULL || hash == ht->key_hash_function(key)); + return hash_table_search(ht, hash, key); +} + +static struct hash_entry * +hash_table_insert(struct hash_table *ht, uint32_t hash, + const void *key, void *data); + +static void +_mesa_hash_table_rehash(struct hash_table *ht, unsigned new_size_index) +{ + struct hash_table old_ht; + struct hash_entry *table, *entry; + + if (new_size_index >= ARRAY_SIZE(hash_sizes)) + return; + + table = rzalloc_array(ht, struct hash_entry, + hash_sizes[new_size_index].size); + if (table == NULL) + return; + + old_ht = *ht; + + ht->table = table; + ht->size_index = new_size_index; + ht->size = hash_sizes[ht->size_index].size; + ht->rehash = hash_sizes[ht->size_index].rehash; + ht->max_entries = hash_sizes[ht->size_index].max_entries; + ht->entries = 0; + ht->deleted_entries = 0; + + hash_table_foreach(&old_ht, entry) { + hash_table_insert(ht, entry->hash, entry->key, entry->data); + } + + ralloc_free(old_ht.table); +} + +static struct hash_entry * +hash_table_insert(struct hash_table *ht, uint32_t hash, + const void *key, void *data) +{ + uint32_t start_hash_address, hash_address; + struct hash_entry *available_entry = NULL; + + if (ht->entries >= ht->max_entries) { + _mesa_hash_table_rehash(ht, ht->size_index + 1); + } else if (ht->deleted_entries + ht->entries >= ht->max_entries) { + _mesa_hash_table_rehash(ht, ht->size_index); + } + + start_hash_address = hash % ht->size; + hash_address = start_hash_address; + do { + struct hash_entry *entry = ht->table + hash_address; + uint32_t double_hash; + + if (!entry_is_present(ht, entry)) { + /* Stash the first available entry we find */ + if (available_entry == NULL) + available_entry = entry; + if (entry_is_free(entry)) + break; + } + + /* Implement replacement when another insert happens + * with a matching key. This is a relatively common + * feature of hash tables, with the alternative + * generally being "insert the new value as well, and + * return it first when the key is searched for". + * + * Note that the hash table doesn't have a delete + * callback. If freeing of old data pointers is + * required to avoid memory leaks, perform a search + * before inserting. + */ + if (entry->hash == hash && + ht->key_equals_function(key, entry->key)) { + entry->key = key; + entry->data = data; + return entry; + } + + + double_hash = 1 + hash % ht->rehash; + + hash_address = (hash_address + double_hash) % ht->size; + } while (hash_address != start_hash_address); + + if (available_entry) { + if (entry_is_deleted(ht, available_entry)) + ht->deleted_entries--; + available_entry->hash = hash; + available_entry->key = key; + available_entry->data = data; + ht->entries++; + return available_entry; + } + + /* We could hit here if a required resize failed. An unchecked-malloc + * application could ignore this result. + */ + return NULL; +} + +/** + * Inserts the key with the given hash into the table. + * + * Note that insertion may rearrange the table on a resize or rehash, + * so previously found hash_entries are no longer valid after this function. + */ +struct hash_entry * +_mesa_hash_table_insert(struct hash_table *ht, const void *key, void *data) +{ + assert(ht->key_hash_function); + return hash_table_insert(ht, ht->key_hash_function(key), key, data); +} + +struct hash_entry * +_mesa_hash_table_insert_pre_hashed(struct hash_table *ht, uint32_t hash, + const void *key, void *data) +{ + assert(ht->key_hash_function == NULL || hash == ht->key_hash_function(key)); + return hash_table_insert(ht, hash, key, data); +} + +/** + * This function deletes the given hash table entry. + * + * Note that deletion doesn't otherwise modify the table, so an iteration over + * the table deleting entries is safe. + */ +void +_mesa_hash_table_remove(struct hash_table *ht, + struct hash_entry *entry) +{ + if (!entry) + return; + + entry->key = ht->deleted_key; + ht->entries--; + ht->deleted_entries++; +} + +/** + * This function is an iterator over the hash table. + * + * Pass in NULL for the first entry, as in the start of a for loop. Note that + * an iteration over the table is O(table_size) not O(entries). + */ +struct hash_entry * +_mesa_hash_table_next_entry(struct hash_table *ht, + struct hash_entry *entry) +{ + if (entry == NULL) + entry = ht->table; + else + entry = entry + 1; + + for (; entry != ht->table + ht->size; entry++) { + if (entry_is_present(ht, entry)) { + return entry; + } + } + + return NULL; +} + +/** + * Returns a random entry from the hash table. + * + * This may be useful in implementing random replacement (as opposed + * to just removing everything) in caches based on this hash table + * implementation. @predicate may be used to filter entries, or may + * be set to NULL for no filtering. + */ +struct hash_entry * +_mesa_hash_table_random_entry(struct hash_table *ht, + bool (*predicate)(struct hash_entry *entry)) +{ + struct hash_entry *entry; + uint32_t i = rand() % ht->size; + + if (ht->entries == 0) + return NULL; + + for (entry = ht->table + i; entry != ht->table + ht->size; entry++) { + if (entry_is_present(ht, entry) && + (!predicate || predicate(entry))) { + return entry; + } + } + + for (entry = ht->table; entry != ht->table + i; entry++) { + if (entry_is_present(ht, entry) && + (!predicate || predicate(entry))) { + return entry; + } + } + + return NULL; +} + + +/** + * Quick FNV-1a hash implementation based on: + * http://www.isthe.com/chongo/tech/comp/fnv/ + * + * FNV-1a is not be the best hash out there -- Jenkins's lookup3 is supposed + * to be quite good, and it probably beats FNV. But FNV has the advantage + * that it involves almost no code. For an improvement on both, see Paul + * Hsieh's http://www.azillionmonkeys.com/qed/hash.html + */ +uint32_t +_mesa_hash_data(const void *data, size_t size) +{ + return _mesa_fnv32_1a_accumulate_block(_mesa_fnv32_1a_offset_bias, + data, size); +} + +/** FNV-1a string hash implementation */ +uint32_t +_mesa_hash_string(const char *key) +{ + uint32_t hash = _mesa_fnv32_1a_offset_bias; + + while (*key != 0) { + hash = _mesa_fnv32_1a_accumulate(hash, *key); + key++; + } + + return hash; +} + +/** + * String compare function for use as the comparison callback in + * _mesa_hash_table_create(). + */ +bool +_mesa_key_string_equal(const void *a, const void *b) +{ + return strcmp(a, b) == 0; +} + +bool +_mesa_key_pointer_equal(const void *a, const void *b) +{ + return a == b; +} diff --git a/lib/mesa/src/util/hash_table.h b/lib/mesa/src/util/hash_table.h new file mode 100644 index 000000000..eb9dbc333 --- /dev/null +++ b/lib/mesa/src/util/hash_table.h @@ -0,0 +1,137 @@ +/* + * Copyright © 2009,2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +#ifndef _HASH_TABLE_H +#define _HASH_TABLE_H + +#include +#include +#include +#include "c99_compat.h" +#include "macros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct hash_entry { + uint32_t hash; + const void *key; + void *data; +}; + +struct hash_table { + struct hash_entry *table; + uint32_t (*key_hash_function)(const void *key); + bool (*key_equals_function)(const void *a, const void *b); + const void *deleted_key; + uint32_t size; + uint32_t rehash; + uint32_t max_entries; + uint32_t size_index; + uint32_t entries; + uint32_t deleted_entries; +}; + +struct hash_table * +_mesa_hash_table_create(void *mem_ctx, + uint32_t (*key_hash_function)(const void *key), + bool (*key_equals_function)(const void *a, + const void *b)); +void _mesa_hash_table_destroy(struct hash_table *ht, + void (*delete_function)(struct hash_entry *entry)); +void _mesa_hash_table_set_deleted_key(struct hash_table *ht, + const void *deleted_key); + +struct hash_entry * +_mesa_hash_table_insert(struct hash_table *ht, const void *key, void *data); +struct hash_entry * +_mesa_hash_table_insert_pre_hashed(struct hash_table *ht, uint32_t hash, + const void *key, void *data); +struct hash_entry * +_mesa_hash_table_search(struct hash_table *ht, const void *key); +struct hash_entry * +_mesa_hash_table_search_pre_hashed(struct hash_table *ht, uint32_t hash, + const void *key); +void _mesa_hash_table_remove(struct hash_table *ht, + struct hash_entry *entry); + +struct hash_entry *_mesa_hash_table_next_entry(struct hash_table *ht, + struct hash_entry *entry); +struct hash_entry * +_mesa_hash_table_random_entry(struct hash_table *ht, + bool (*predicate)(struct hash_entry *entry)); + +uint32_t _mesa_hash_data(const void *data, size_t size); +uint32_t _mesa_hash_string(const char *key); +bool _mesa_key_string_equal(const void *a, const void *b); +bool _mesa_key_pointer_equal(const void *a, const void *b); + +static inline uint32_t _mesa_key_hash_string(const void *key) +{ + return _mesa_hash_string((const char *)key); +} + +static inline uint32_t _mesa_hash_pointer(const void *pointer) +{ + return _mesa_hash_data(&pointer, sizeof(pointer)); +} + +static const uint32_t _mesa_fnv32_1a_offset_bias = 2166136261u; + +static inline uint32_t +_mesa_fnv32_1a_accumulate_block(uint32_t hash, const void *data, size_t size) +{ + const uint8_t *bytes = (const uint8_t *)data; + + while (size-- != 0) { + hash ^= *bytes; + hash = hash * 0x01000193; + bytes++; + } + + return hash; +} + +#define _mesa_fnv32_1a_accumulate(hash, expr) \ + _mesa_fnv32_1a_accumulate_block(hash, &(expr), sizeof(expr)) + +/** + * This foreach function is safe against deletion (which just replaces + * an entry's data with the deleted marker), but not against insertion + * (which may rehash the table, making entry a dangling pointer). + */ +#define hash_table_foreach(ht, entry) \ + for (entry = _mesa_hash_table_next_entry(ht, NULL); \ + entry != NULL; \ + entry = _mesa_hash_table_next_entry(ht, entry)) + +#ifdef __cplusplus +} /* extern C */ +#endif + +#endif /* _HASH_TABLE_H */ diff --git a/lib/mesa/src/util/list.h b/lib/mesa/src/util/list.h new file mode 100644 index 000000000..b98ce59ff --- /dev/null +++ b/lib/mesa/src/util/list.h @@ -0,0 +1,211 @@ +/************************************************************************** + * + * Copyright 2006 VMware, Inc., Bismarck, ND. USA. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + +/** + * \file + * List macros heavily inspired by the Linux kernel + * list handling. No list looping yet. + * + * Is not threadsafe, so common operations need to + * be protected using an external mutex. + */ + +#ifndef _UTIL_LIST_H_ +#define _UTIL_LIST_H_ + + +#include +#include +#include + + +struct list_head +{ + struct list_head *prev; + struct list_head *next; +}; + +static inline void list_inithead(struct list_head *item) +{ + item->prev = item; + item->next = item; +} + +static inline void list_add(struct list_head *item, struct list_head *list) +{ + item->prev = list; + item->next = list->next; + list->next->prev = item; + list->next = item; +} + +static inline void list_addtail(struct list_head *item, struct list_head *list) +{ + item->next = list; + item->prev = list->prev; + list->prev->next = item; + list->prev = item; +} + +static inline void list_replace(struct list_head *from, struct list_head *to) +{ + to->prev = from->prev; + to->next = from->next; + from->next->prev = to; + from->prev->next = to; +} + +static inline void list_del(struct list_head *item) +{ + item->prev->next = item->next; + item->next->prev = item->prev; + item->prev = item->next = NULL; +} + +static inline void list_delinit(struct list_head *item) +{ + item->prev->next = item->next; + item->next->prev = item->prev; + item->next = item; + item->prev = item; +} + +static inline bool list_empty(struct list_head *list) +{ + return list->next == list; +} + +static inline unsigned list_length(struct list_head *list) +{ + struct list_head *node; + unsigned length = 0; + for (node = list->next; node != list; node = node->next) + length++; + return length; +} + +static inline void list_validate(struct list_head *list) +{ + struct list_head *node; + assert(list->next->prev == list && list->prev->next == list); + for (node = list->next; node != list; node = node->next) + assert(node->next->prev == node && node->prev->next == node); +} + +#define LIST_INITHEAD(__item) list_inithead(__item) +#define LIST_ADD(__item, __list) list_add(__item, __list) +#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list) +#define LIST_REPLACE(__from, __to) list_replace(__from, __to) +#define LIST_DEL(__item) list_del(__item) +#define LIST_DELINIT(__item) list_delinit(__item) + +#define LIST_ENTRY(__type, __item, __field) \ + ((__type *)(((char *)(__item)) - offsetof(__type, __field))) + +#define LIST_IS_EMPTY(__list) \ + ((__list)->next == (__list)) + +/** + * Cast from a pointer to a member of a struct back to the containing struct. + * + * 'sample' MUST be initialized, or else the result is undefined! + */ +#ifndef container_of +#define container_of(ptr, sample, member) \ + (void *)((char *)(ptr) \ + - ((char *)&(sample)->member - (char *)(sample))) +#endif + +#define list_first_entry(ptr, type, member) \ + LIST_ENTRY(type, (ptr)->next, member) + +#define list_last_entry(ptr, type, member) \ + LIST_ENTRY(type, (ptr)->prev, member) + + +#define LIST_FOR_EACH_ENTRY(pos, head, member) \ + for (pos = NULL, pos = container_of((head)->next, pos, member); \ + &pos->member != (head); \ + pos = container_of(pos->member.next, pos, member)) + +#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \ + for (pos = NULL, pos = container_of((head)->next, pos, member), \ + storage = container_of(pos->member.next, pos, member); \ + &pos->member != (head); \ + pos = storage, storage = container_of(storage->member.next, storage, member)) + +#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \ + for (pos = NULL, pos = container_of((head)->prev, pos, member), \ + storage = container_of(pos->member.prev, pos, member); \ + &pos->member != (head); \ + pos = storage, storage = container_of(storage->member.prev, storage, member)) + +#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \ + for (pos = NULL, pos = container_of((start), pos, member); \ + &pos->member != (head); \ + pos = container_of(pos->member.next, pos, member)) + +#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \ + for (pos = NULL, pos = container_of((start), pos, member); \ + &pos->member != (head); \ + pos = container_of(pos->member.prev, pos, member)) + +#define list_for_each_entry(type, pos, head, member) \ + for (type *pos = LIST_ENTRY(type, (head)->next, member); \ + &pos->member != (head); \ + pos = LIST_ENTRY(type, pos->member.next, member)) + +#define list_for_each_entry_safe(type, pos, head, member) \ + for (type *pos = LIST_ENTRY(type, (head)->next, member), \ + *__next = LIST_ENTRY(type, pos->member.next, member); \ + &pos->member != (head); \ + pos = __next, \ + __next = LIST_ENTRY(type, __next->member.next, member)) + +#define list_for_each_entry_rev(type, pos, head, member) \ + for (type *pos = LIST_ENTRY(type, (head)->prev, member); \ + &pos->member != (head); \ + pos = LIST_ENTRY(type, pos->member.prev, member)) + +#define list_for_each_entry_safe_rev(type, pos, head, member) \ + for (type *pos = LIST_ENTRY(type, (head)->prev, member), \ + *__prev = LIST_ENTRY(type, pos->member.prev, member); \ + &pos->member != (head); \ + pos = __prev, \ + __prev = LIST_ENTRY(type, __prev->member.prev, member)) + +#define list_for_each_entry_from(type, pos, start, head, member) \ + for (type *pos = LIST_ENTRY(type, (start), member); \ + &pos->member != (head); \ + pos = LIST_ENTRY(type, pos->member.next, member)) + +#define list_for_each_entry_from_rev(type, pos, start, head, member) \ + for (type *pos = LIST_ENTRY(type, (start), member); \ + &pos->member != (head); \ + pos = LIST_ENTRY(type, pos->member.prev, member)) + +#endif /*_UTIL_LIST_H_*/ diff --git a/lib/mesa/src/util/macros.h b/lib/mesa/src/util/macros.h new file mode 100644 index 000000000..84e4f182b --- /dev/null +++ b/lib/mesa/src/util/macros.h @@ -0,0 +1,214 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UTIL_MACROS_H +#define UTIL_MACROS_H + +/* Compute the size of an array */ +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) +#endif + +/* For compatibility with Clang's __has_builtin() */ +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +/** + * __builtin_expect macros + */ +#if !defined(HAVE___BUILTIN_EXPECT) +# define __builtin_expect(x, y) (x) +#endif + +#ifndef likely +# ifdef HAVE___BUILTIN_EXPECT +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +# else +# define likely(x) (x) +# define unlikely(x) (x) +# endif +#endif + + +/** + * Static (compile-time) assertion. + * Basically, use COND to dimension an array. If COND is false/zero the + * array size will be -1 and we'll get a compilation error. + */ +#define STATIC_ASSERT(COND) \ + do { \ + (void) sizeof(char [1 - 2*!(COND)]); \ + } while (0) + + +/** + * Unreachable macro. Useful for suppressing "control reaches end of non-void + * function" warnings. + */ +#ifdef HAVE___BUILTIN_UNREACHABLE +#define unreachable(str) \ +do { \ + assert(!str); \ + __builtin_unreachable(); \ +} while (0) +#elif defined (_MSC_VER) +#define unreachable(str) \ +do { \ + assert(!str); \ + __assume(0); \ +} while (0) +#else +#define unreachable(str) assert(!str) +#endif + +/** + * Assume macro. Useful for expressing our assumptions to the compiler, + * typically for purposes of silencing warnings. + */ +#if __has_builtin(__builtin_assume) +#define assume(expr) \ +do { \ + assert(expr); \ + __builtin_assume(expr); \ +} while (0) +#elif defined HAVE___BUILTIN_UNREACHABLE +#define assume(expr) ((expr) ? ((void) 0) \ + : (assert(!"assumption failed"), \ + __builtin_unreachable())) +#elif defined (_MSC_VER) +#define assume(expr) __assume(expr) +#else +#define assume(expr) assert(expr) +#endif + +/* Attribute const is used for functions that have no effects other than their + * return value, and only rely on the argument values to compute the return + * value. As a result, calls to it can be CSEed. Note that using memory + * pointed to by the arguments is not allowed for const functions. + */ +#ifdef HAVE_FUNC_ATTRIBUTE_CONST +#define ATTRIBUTE_CONST __attribute__((__const__)) +#else +#define ATTRIBUTE_CONST +#endif + +#ifdef HAVE_FUNC_ATTRIBUTE_FLATTEN +#define FLATTEN __attribute__((__flatten__)) +#else +#define FLATTEN +#endif + +#ifdef HAVE_FUNC_ATTRIBUTE_FORMAT +#define PRINTFLIKE(f, a) __attribute__ ((format(__printf__, f, a))) +#else +#define PRINTFLIKE(f, a) +#endif + +#ifdef HAVE_FUNC_ATTRIBUTE_MALLOC +#define MALLOCLIKE __attribute__((__malloc__)) +#else +#define MALLOCLIKE +#endif + +/* Used to optionally mark structures with misaligned elements or size as + * packed, to trade off performance for space. + */ +#ifdef HAVE_FUNC_ATTRIBUTE_PACKED +#define PACKED __attribute__((__packed__)) +#else +#define PACKED +#endif + +/* Attribute pure is used for functions that have no effects other than their + * return value. As a result, calls to it can be dead code eliminated. + */ +#ifdef HAVE_FUNC_ATTRIBUTE_PURE +#define ATTRIBUTE_PURE __attribute__((__pure__)) +#else +#define ATTRIBUTE_PURE +#endif + +#ifdef __cplusplus +/** + * Macro function that evaluates to true if T is a trivially + * destructible type -- that is, if its (non-virtual) destructor + * performs no action and all member variables and base classes are + * trivially destructible themselves. + */ +# if defined(__GNUC__) +# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))) +# define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) +# endif +# elif (defined(__clang__) && defined(__has_feature)) +# if __has_feature(has_trivial_destructor) +# define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) +# endif +# endif +# ifndef HAS_TRIVIAL_DESTRUCTOR + /* It's always safe (if inefficient) to assume that a + * destructor is non-trivial. + */ +# define HAS_TRIVIAL_DESTRUCTOR(T) (false) +# endif +#endif + +/** + * PUBLIC/USED macros + * + * If we build the library with gcc's -fvisibility=hidden flag, we'll + * use the PUBLIC macro to mark functions that are to be exported. + * + * We also need to define a USED attribute, so the optimizer doesn't + * inline a static function that we later use in an alias. - ajax + */ +#ifndef PUBLIC +# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# define PUBLIC __attribute__((visibility("default"))) +# define USED __attribute__((used)) +# elif defined(_MSC_VER) +# define PUBLIC __declspec(dllexport) +# define USED +# else +# define PUBLIC +# define USED +# endif +#endif + +#ifdef HAVE_FUNC_ATTRIBUTE_UNUSED +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif + +#ifdef HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT +#define MUST_CHECK __attribute__((warn_unused_result)) +#else +#define MUST_CHECK +#endif + +/** Compute ceiling of integer quotient of A divided by B. */ +#define DIV_ROUND_UP( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) + +#endif /* UTIL_MACROS_H */ diff --git a/lib/mesa/src/util/ralloc.c b/lib/mesa/src/util/ralloc.c new file mode 100644 index 000000000..01719c888 --- /dev/null +++ b/lib/mesa/src/util/ralloc.c @@ -0,0 +1,518 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +/* Android defines SIZE_MAX in limits.h, instead of the standard stdint.h */ +#ifdef ANDROID +#include +#endif + +/* Some versions of MinGW are missing _vscprintf's declaration, although they + * still provide the symbol in the import library. */ +#ifdef __MINGW32__ +_CRTIMP int _vscprintf(const char *format, va_list argptr); +#endif + +#include "ralloc.h" + +#ifndef va_copy +#ifdef __va_copy +#define va_copy(dest, src) __va_copy((dest), (src)) +#else +#define va_copy(dest, src) (dest) = (src) +#endif +#endif + +#define CANARY 0x5A1106 + +struct ralloc_header +{ +#ifdef DEBUG + /* A canary value used to determine whether a pointer is ralloc'd. */ + unsigned canary; +#endif + + struct ralloc_header *parent; + + /* The first child (head of a linked list) */ + struct ralloc_header *child; + + /* Linked list of siblings */ + struct ralloc_header *prev; + struct ralloc_header *next; + + void (*destructor)(void *); +}; + +typedef struct ralloc_header ralloc_header; + +static void unlink_block(ralloc_header *info); +static void unsafe_free(ralloc_header *info); + +static ralloc_header * +get_header(const void *ptr) +{ + ralloc_header *info = (ralloc_header *) (((char *) ptr) - + sizeof(ralloc_header)); +#ifdef DEBUG + assert(info->canary == CANARY); +#endif + return info; +} + +#define PTR_FROM_HEADER(info) (((char *) info) + sizeof(ralloc_header)) + +static void +add_child(ralloc_header *parent, ralloc_header *info) +{ + if (parent != NULL) { + info->parent = parent; + info->next = parent->child; + parent->child = info; + + if (info->next != NULL) + info->next->prev = info; + } +} + +void * +ralloc_context(const void *ctx) +{ + return ralloc_size(ctx, 0); +} + +void * +ralloc_size(const void *ctx, size_t size) +{ + void *block = calloc(1, size + sizeof(ralloc_header)); + ralloc_header *info; + ralloc_header *parent; + + if (unlikely(block == NULL)) + return NULL; + info = (ralloc_header *) block; + parent = ctx != NULL ? get_header(ctx) : NULL; + + add_child(parent, info); + +#ifdef DEBUG + info->canary = CANARY; +#endif + + return PTR_FROM_HEADER(info); +} + +void * +rzalloc_size(const void *ctx, size_t size) +{ + void *ptr = ralloc_size(ctx, size); + if (likely(ptr != NULL)) + memset(ptr, 0, size); + return ptr; +} + +/* helper function - assumes ptr != NULL */ +static void * +resize(void *ptr, size_t size) +{ + ralloc_header *child, *old, *info; + + old = get_header(ptr); + info = realloc(old, size + sizeof(ralloc_header)); + + if (info == NULL) + return NULL; + + /* Update parent and sibling's links to the reallocated node. */ + if (info != old && info->parent != NULL) { + if (info->parent->child == old) + info->parent->child = info; + + if (info->prev != NULL) + info->prev->next = info; + + if (info->next != NULL) + info->next->prev = info; + } + + /* Update child->parent links for all children */ + for (child = info->child; child != NULL; child = child->next) + child->parent = info; + + return PTR_FROM_HEADER(info); +} + +void * +reralloc_size(const void *ctx, void *ptr, size_t size) +{ + if (unlikely(ptr == NULL)) + return ralloc_size(ctx, size); + + assert(ralloc_parent(ptr) == ctx); + return resize(ptr, size); +} + +void * +ralloc_array_size(const void *ctx, size_t size, unsigned count) +{ + if (count > SIZE_MAX/size) + return NULL; + + return ralloc_size(ctx, size * count); +} + +void * +rzalloc_array_size(const void *ctx, size_t size, unsigned count) +{ + if (count > SIZE_MAX/size) + return NULL; + + return rzalloc_size(ctx, size * count); +} + +void * +reralloc_array_size(const void *ctx, void *ptr, size_t size, unsigned count) +{ + if (count > SIZE_MAX/size) + return NULL; + + return reralloc_size(ctx, ptr, size * count); +} + +void +ralloc_free(void *ptr) +{ + ralloc_header *info; + + if (ptr == NULL) + return; + + info = get_header(ptr); + unlink_block(info); + unsafe_free(info); +} + +static void +unlink_block(ralloc_header *info) +{ + /* Unlink from parent & siblings */ + if (info->parent != NULL) { + if (info->parent->child == info) + info->parent->child = info->next; + + if (info->prev != NULL) + info->prev->next = info->next; + + if (info->next != NULL) + info->next->prev = info->prev; + } + info->parent = NULL; + info->prev = NULL; + info->next = NULL; +} + +static void +unsafe_free(ralloc_header *info) +{ + /* Recursively free any children...don't waste time unlinking them. */ + ralloc_header *temp; + while (info->child != NULL) { + temp = info->child; + info->child = temp->next; + unsafe_free(temp); + } + + /* Free the block itself. Call the destructor first, if any. */ + if (info->destructor != NULL) + info->destructor(PTR_FROM_HEADER(info)); + + free(info); +} + +void +ralloc_steal(const void *new_ctx, void *ptr) +{ + ralloc_header *info, *parent; + + if (unlikely(ptr == NULL)) + return; + + info = get_header(ptr); + parent = get_header(new_ctx); + + unlink_block(info); + + add_child(parent, info); +} + +void +ralloc_adopt(const void *new_ctx, void *old_ctx) +{ + ralloc_header *new_info, *old_info, *child; + + if (unlikely(old_ctx == NULL)) + return; + + old_info = get_header(old_ctx); + new_info = get_header(new_ctx); + + /* If there are no children, bail. */ + if (unlikely(old_info->child == NULL)) + return; + + /* Set all the children's parent to new_ctx; get a pointer to the last child. */ + for (child = old_info->child; child->next != NULL; child = child->next) { + child->parent = new_info; + } + + /* Connect the two lists together; parent them to new_ctx; make old_ctx empty. */ + child->next = new_info->child; + new_info->child = old_info->child; + old_info->child = NULL; +} + +void * +ralloc_parent(const void *ptr) +{ + ralloc_header *info; + + if (unlikely(ptr == NULL)) + return NULL; + + info = get_header(ptr); + return info->parent ? PTR_FROM_HEADER(info->parent) : NULL; +} + +static void *autofree_context = NULL; + +static void +autofree(void) +{ + ralloc_free(autofree_context); +} + +void * +ralloc_autofree_context(void) +{ + if (unlikely(autofree_context == NULL)) { + autofree_context = ralloc_context(NULL); + atexit(autofree); + } + return autofree_context; +} + +void +ralloc_set_destructor(const void *ptr, void(*destructor)(void *)) +{ + ralloc_header *info = get_header(ptr); + info->destructor = destructor; +} + +char * +ralloc_strdup(const void *ctx, const char *str) +{ + size_t n; + char *ptr; + + if (unlikely(str == NULL)) + return NULL; + + n = strlen(str); + ptr = ralloc_array(ctx, char, n + 1); + memcpy(ptr, str, n); + ptr[n] = '\0'; + return ptr; +} + +char * +ralloc_strndup(const void *ctx, const char *str, size_t max) +{ + size_t n; + char *ptr; + + if (unlikely(str == NULL)) + return NULL; + + n = strlen(str); + if (n > max) + n = max; + + ptr = ralloc_array(ctx, char, n + 1); + memcpy(ptr, str, n); + ptr[n] = '\0'; + return ptr; +} + +/* helper routine for strcat/strncat - n is the exact amount to copy */ +static bool +cat(char **dest, const char *str, size_t n) +{ + char *both; + size_t existing_length; + assert(dest != NULL && *dest != NULL); + + existing_length = strlen(*dest); + both = resize(*dest, existing_length + n + 1); + if (unlikely(both == NULL)) + return false; + + memcpy(both + existing_length, str, n); + both[existing_length + n] = '\0'; + + *dest = both; + return true; +} + + +bool +ralloc_strcat(char **dest, const char *str) +{ + return cat(dest, str, strlen(str)); +} + +bool +ralloc_strncat(char **dest, const char *str, size_t n) +{ + /* Clamp n to the string length */ + size_t str_length = strlen(str); + if (str_length < n) + n = str_length; + + return cat(dest, str, n); +} + +char * +ralloc_asprintf(const void *ctx, const char *fmt, ...) +{ + char *ptr; + va_list args; + va_start(args, fmt); + ptr = ralloc_vasprintf(ctx, fmt, args); + va_end(args); + return ptr; +} + +/* Return the length of the string that would be generated by a printf-style + * format and argument list, not including the \0 byte. + */ +static size_t +printf_length(const char *fmt, va_list untouched_args) +{ + int size; + char junk; + + /* Make a copy of the va_list so the original caller can still use it */ + va_list args; + va_copy(args, untouched_args); + +#ifdef _WIN32 + /* We need to use _vcsprintf to calculate the size as vsnprintf returns -1 + * if the number of characters to write is greater than count. + */ + size = _vscprintf(fmt, args); + (void)junk; +#else + size = vsnprintf(&junk, 1, fmt, args); +#endif + assert(size >= 0); + + va_end(args); + + return size; +} + +char * +ralloc_vasprintf(const void *ctx, const char *fmt, va_list args) +{ + size_t size = printf_length(fmt, args) + 1; + + char *ptr = ralloc_size(ctx, size); + if (ptr != NULL) + vsnprintf(ptr, size, fmt, args); + + return ptr; +} + +bool +ralloc_asprintf_append(char **str, const char *fmt, ...) +{ + bool success; + va_list args; + va_start(args, fmt); + success = ralloc_vasprintf_append(str, fmt, args); + va_end(args); + return success; +} + +bool +ralloc_vasprintf_append(char **str, const char *fmt, va_list args) +{ + size_t existing_length; + assert(str != NULL); + existing_length = *str ? strlen(*str) : 0; + return ralloc_vasprintf_rewrite_tail(str, &existing_length, fmt, args); +} + +bool +ralloc_asprintf_rewrite_tail(char **str, size_t *start, const char *fmt, ...) +{ + bool success; + va_list args; + va_start(args, fmt); + success = ralloc_vasprintf_rewrite_tail(str, start, fmt, args); + va_end(args); + return success; +} + +bool +ralloc_vasprintf_rewrite_tail(char **str, size_t *start, const char *fmt, + va_list args) +{ + size_t new_length; + char *ptr; + + assert(str != NULL); + + if (unlikely(*str == NULL)) { + // Assuming a NULL context is probably bad, but it's expected behavior. + *str = ralloc_vasprintf(NULL, fmt, args); + return true; + } + + new_length = printf_length(fmt, args); + + ptr = resize(*str, *start + new_length + 1); + if (unlikely(ptr == NULL)) + return false; + + vsnprintf(ptr + *start, new_length + 1, fmt, args); + *str = ptr; + *start += new_length; + return true; +} diff --git a/lib/mesa/src/util/ralloc.h b/lib/mesa/src/util/ralloc.h new file mode 100644 index 000000000..7587e1190 --- /dev/null +++ b/lib/mesa/src/util/ralloc.h @@ -0,0 +1,452 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file ralloc.h + * + * ralloc: a recursive memory allocator + * + * The ralloc memory allocator creates a hierarchy of allocated + * objects. Every allocation is in reference to some parent, and + * every allocated object can in turn be used as the parent of a + * subsequent allocation. This allows for extremely convenient + * discarding of an entire tree/sub-tree of allocations by calling + * ralloc_free on any particular object to free it and all of its + * children. + * + * The conceptual working of ralloc was directly inspired by Andrew + * Tridgell's talloc, but ralloc is an independent implementation + * released under the MIT license and tuned for Mesa. + * + * talloc is more sophisticated than ralloc in that it includes reference + * counting and useful debugging features. However, it is released under + * a non-permissive open source license. + */ + +#ifndef RALLOC_H +#define RALLOC_H + +#include +#include +#include + +#include "macros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \def ralloc(ctx, type) + * Allocate a new object chained off of the given context. + * + * This is equivalent to: + * \code + * ((type *) ralloc_size(ctx, sizeof(type)) + * \endcode + */ +#define ralloc(ctx, type) ((type *) ralloc_size(ctx, sizeof(type))) + +/** + * \def rzalloc(ctx, type) + * Allocate a new object out of the given context and initialize it to zero. + * + * This is equivalent to: + * \code + * ((type *) rzalloc_size(ctx, sizeof(type)) + * \endcode + */ +#define rzalloc(ctx, type) ((type *) rzalloc_size(ctx, sizeof(type))) + +/** + * Allocate a new ralloc context. + * + * While any ralloc'd pointer can be used as a context, sometimes it is useful + * to simply allocate a context with no associated memory. + * + * It is equivalent to: + * \code + * ((type *) ralloc_size(ctx, 0) + * \endcode + */ +void *ralloc_context(const void *ctx); + +/** + * Allocate memory chained off of the given context. + * + * This is the core allocation routine which is used by all others. It + * simply allocates storage for \p size bytes and returns the pointer, + * similar to \c malloc. + */ +void *ralloc_size(const void *ctx, size_t size) MALLOCLIKE; + +/** + * Allocate zero-initialized memory chained off of the given context. + * + * This is similar to \c calloc with a size of 1. + */ +void *rzalloc_size(const void *ctx, size_t size) MALLOCLIKE; + +/** + * Resize a piece of ralloc-managed memory, preserving data. + * + * Similar to \c realloc. Unlike C89, passing 0 for \p size does not free the + * memory. Instead, it resizes it to a 0-byte ralloc context, just like + * calling ralloc_size(ctx, 0). This is different from talloc. + * + * \param ctx The context to use for new allocation. If \p ptr != NULL, + * it must be the same as ralloc_parent(\p ptr). + * \param ptr Pointer to the memory to be resized. May be NULL. + * \param size The amount of memory to allocate, in bytes. + */ +void *reralloc_size(const void *ctx, void *ptr, size_t size); + +/// \defgroup array Array Allocators @{ + +/** + * \def ralloc_array(ctx, type, count) + * Allocate an array of objects chained off the given context. + * + * Similar to \c calloc, but does not initialize the memory to zero. + * + * More than a convenience function, this also checks for integer overflow when + * multiplying \c sizeof(type) and \p count. This is necessary for security. + * + * This is equivalent to: + * \code + * ((type *) ralloc_array_size(ctx, sizeof(type), count) + * \endcode + */ +#define ralloc_array(ctx, type, count) \ + ((type *) ralloc_array_size(ctx, sizeof(type), count)) + +/** + * \def rzalloc_array(ctx, type, count) + * Allocate a zero-initialized array chained off the given context. + * + * Similar to \c calloc. + * + * More than a convenience function, this also checks for integer overflow when + * multiplying \c sizeof(type) and \p count. This is necessary for security. + * + * This is equivalent to: + * \code + * ((type *) rzalloc_array_size(ctx, sizeof(type), count) + * \endcode + */ +#define rzalloc_array(ctx, type, count) \ + ((type *) rzalloc_array_size(ctx, sizeof(type), count)) + +/** + * \def reralloc(ctx, ptr, type, count) + * Resize a ralloc-managed array, preserving data. + * + * Similar to \c realloc. Unlike C89, passing 0 for \p size does not free the + * memory. Instead, it resizes it to a 0-byte ralloc context, just like + * calling ralloc_size(ctx, 0). This is different from talloc. + * + * More than a convenience function, this also checks for integer overflow when + * multiplying \c sizeof(type) and \p count. This is necessary for security. + * + * \param ctx The context to use for new allocation. If \p ptr != NULL, + * it must be the same as ralloc_parent(\p ptr). + * \param ptr Pointer to the array to be resized. May be NULL. + * \param type The element type. + * \param count The number of elements to allocate. + */ +#define reralloc(ctx, ptr, type, count) \ + ((type *) reralloc_array_size(ctx, ptr, sizeof(type), count)) + +/** + * Allocate memory for an array chained off the given context. + * + * Similar to \c calloc, but does not initialize the memory to zero. + * + * More than a convenience function, this also checks for integer overflow when + * multiplying \p size and \p count. This is necessary for security. + */ +void *ralloc_array_size(const void *ctx, size_t size, unsigned count) MALLOCLIKE; + +/** + * Allocate a zero-initialized array chained off the given context. + * + * Similar to \c calloc. + * + * More than a convenience function, this also checks for integer overflow when + * multiplying \p size and \p count. This is necessary for security. + */ +void *rzalloc_array_size(const void *ctx, size_t size, unsigned count) MALLOCLIKE; + +/** + * Resize a ralloc-managed array, preserving data. + * + * Similar to \c realloc. Unlike C89, passing 0 for \p size does not free the + * memory. Instead, it resizes it to a 0-byte ralloc context, just like + * calling ralloc_size(ctx, 0). This is different from talloc. + * + * More than a convenience function, this also checks for integer overflow when + * multiplying \c sizeof(type) and \p count. This is necessary for security. + * + * \param ctx The context to use for new allocation. If \p ptr != NULL, + * it must be the same as ralloc_parent(\p ptr). + * \param ptr Pointer to the array to be resized. May be NULL. + * \param size The size of an individual element. + * \param count The number of elements to allocate. + * + * \return True unless allocation failed. + */ +void *reralloc_array_size(const void *ctx, void *ptr, size_t size, + unsigned count); +/// @} + +/** + * Free a piece of ralloc-managed memory. + * + * This will also free the memory of any children allocated this context. + */ +void ralloc_free(void *ptr); + +/** + * "Steal" memory from one context, changing it to another. + * + * This changes \p ptr's context to \p new_ctx. This is quite useful if + * memory is allocated out of a temporary context. + */ +void ralloc_steal(const void *new_ctx, void *ptr); + +/** + * Reparent all children from one context to another. + * + * This effectively calls ralloc_steal(new_ctx, child) for all children of \p old_ctx. + */ +void ralloc_adopt(const void *new_ctx, void *old_ctx); + +/** + * Return the given pointer's ralloc context. + */ +void *ralloc_parent(const void *ptr); + +/** + * Return a context whose memory will be automatically freed at program exit. + * + * The first call to this function creates a context and registers a handler + * to free it using \c atexit. This may cause trouble if used in a library + * loaded with \c dlopen. + */ +void *ralloc_autofree_context(void); + +/** + * Set a callback to occur just before an object is freed. + */ +void ralloc_set_destructor(const void *ptr, void(*destructor)(void *)); + +/// \defgroup array String Functions @{ +/** + * Duplicate a string, allocating the memory from the given context. + */ +char *ralloc_strdup(const void *ctx, const char *str) MALLOCLIKE; + +/** + * Duplicate a string, allocating the memory from the given context. + * + * Like \c strndup, at most \p n characters are copied. If \p str is longer + * than \p n characters, \p n are copied, and a termining \c '\0' byte is added. + */ +char *ralloc_strndup(const void *ctx, const char *str, size_t n) MALLOCLIKE; + +/** + * Concatenate two strings, allocating the necessary space. + * + * This appends \p str to \p *dest, similar to \c strcat, using ralloc_resize + * to expand \p *dest to the appropriate size. \p dest will be updated to the + * new pointer unless allocation fails. + * + * The result will always be null-terminated. + * + * \return True unless allocation failed. + */ +bool ralloc_strcat(char **dest, const char *str); + +/** + * Concatenate two strings, allocating the necessary space. + * + * This appends at most \p n bytes of \p str to \p *dest, using ralloc_resize + * to expand \p *dest to the appropriate size. \p dest will be updated to the + * new pointer unless allocation fails. + * + * The result will always be null-terminated; \p str does not need to be null + * terminated if it is longer than \p n. + * + * \return True unless allocation failed. + */ +bool ralloc_strncat(char **dest, const char *str, size_t n); + +/** + * Print to a string. + * + * This is analogous to \c sprintf, but allocates enough space (using \p ctx + * as the context) for the resulting string. + * + * \return The newly allocated string. + */ +char *ralloc_asprintf (const void *ctx, const char *fmt, ...) PRINTFLIKE(2, 3) MALLOCLIKE; + +/** + * Print to a string, given a va_list. + * + * This is analogous to \c vsprintf, but allocates enough space (using \p ctx + * as the context) for the resulting string. + * + * \return The newly allocated string. + */ +char *ralloc_vasprintf(const void *ctx, const char *fmt, va_list args) MALLOCLIKE; + +/** + * Rewrite the tail of an existing string, starting at a given index. + * + * Overwrites the contents of *str starting at \p start with newly formatted + * text, including a new null-terminator. Allocates more memory as necessary. + * + * This can be used to append formatted text when the length of the existing + * string is already known, saving a strlen() call. + * + * \sa ralloc_asprintf_append + * + * \param str The string to be updated. + * \param start The index to start appending new data at. + * \param fmt A printf-style formatting string + * + * \p str will be updated to the new pointer unless allocation fails. + * \p start will be increased by the length of the newly formatted text. + * + * \return True unless allocation failed. + */ +bool ralloc_asprintf_rewrite_tail(char **str, size_t *start, + const char *fmt, ...) + PRINTFLIKE(3, 4); + +/** + * Rewrite the tail of an existing string, starting at a given index. + * + * Overwrites the contents of *str starting at \p start with newly formatted + * text, including a new null-terminator. Allocates more memory as necessary. + * + * This can be used to append formatted text when the length of the existing + * string is already known, saving a strlen() call. + * + * \sa ralloc_vasprintf_append + * + * \param str The string to be updated. + * \param start The index to start appending new data at. + * \param fmt A printf-style formatting string + * \param args A va_list containing the data to be formatted + * + * \p str will be updated to the new pointer unless allocation fails. + * \p start will be increased by the length of the newly formatted text. + * + * \return True unless allocation failed. + */ +bool ralloc_vasprintf_rewrite_tail(char **str, size_t *start, const char *fmt, + va_list args); + +/** + * Append formatted text to the supplied string. + * + * This is equivalent to + * \code + * ralloc_asprintf_rewrite_tail(str, strlen(*str), fmt, ...) + * \endcode + * + * \sa ralloc_asprintf + * \sa ralloc_asprintf_rewrite_tail + * \sa ralloc_strcat + * + * \p str will be updated to the new pointer unless allocation fails. + * + * \return True unless allocation failed. + */ +bool ralloc_asprintf_append (char **str, const char *fmt, ...) + PRINTFLIKE(2, 3); + +/** + * Append formatted text to the supplied string, given a va_list. + * + * This is equivalent to + * \code + * ralloc_vasprintf_rewrite_tail(str, strlen(*str), fmt, args) + * \endcode + * + * \sa ralloc_vasprintf + * \sa ralloc_vasprintf_rewrite_tail + * \sa ralloc_strcat + * + * \p str will be updated to the new pointer unless allocation fails. + * + * \return True unless allocation failed. + */ +bool ralloc_vasprintf_append(char **str, const char *fmt, va_list args); +/// @} + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +/** + * Declare C++ new and delete operators which use ralloc. + * + * Placing this macro in the body of a class makes it possible to do: + * + * TYPE *var = new(mem_ctx) TYPE(...); + * delete var; + * + * which is more idiomatic in C++ than calling ralloc. + */ +#define DECLARE_RALLOC_CXX_OPERATORS(TYPE) \ +private: \ + static void _ralloc_destructor(void *p) \ + { \ + reinterpret_cast(p)->~TYPE(); \ + } \ +public: \ + static void* operator new(size_t size, void *mem_ctx) \ + { \ + void *p = ralloc_size(mem_ctx, size); \ + assert(p != NULL); \ + if (!HAS_TRIVIAL_DESTRUCTOR(TYPE)) \ + ralloc_set_destructor(p, _ralloc_destructor); \ + return p; \ + } \ + \ + static void operator delete(void *p) \ + { \ + /* The object's destructor is guaranteed to have already been \ + * called by the delete operator at this point -- Make sure it's \ + * not called again. \ + */ \ + if (!HAS_TRIVIAL_DESTRUCTOR(TYPE)) \ + ralloc_set_destructor(p, NULL); \ + ralloc_free(p); \ + } + + +#endif diff --git a/lib/mesa/src/util/register_allocate.c b/lib/mesa/src/util/register_allocate.c new file mode 100644 index 000000000..8af93c040 --- /dev/null +++ b/lib/mesa/src/util/register_allocate.c @@ -0,0 +1,712 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +/** @file register_allocate.c + * + * Graph-coloring register allocator. + * + * The basic idea of graph coloring is to make a node in a graph for + * every thing that needs a register (color) number assigned, and make + * edges in the graph between nodes that interfere (can't be allocated + * to the same register at the same time). + * + * During the "simplify" process, any any node with fewer edges than + * there are registers means that that edge can get assigned a + * register regardless of what its neighbors choose, so that node is + * pushed on a stack and removed (with its edges) from the graph. + * That likely causes other nodes to become trivially colorable as well. + * + * Then during the "select" process, nodes are popped off of that + * stack, their edges restored, and assigned a color different from + * their neighbors. Because they were pushed on the stack only when + * they were trivially colorable, any color chosen won't interfere + * with the registers to be popped later. + * + * The downside to most graph coloring is that real hardware often has + * limitations, like registers that need to be allocated to a node in + * pairs, or aligned on some boundary. This implementation follows + * the paper "Retargetable Graph-Coloring Register Allocation for + * Irregular Architectures" by Johan Runeson and Sven-Olof Nyström. + * + * In this system, there are register classes each containing various + * registers, and registers may interfere with other registers. For + * example, one might have a class of base registers, and a class of + * aligned register pairs that would each interfere with their pair of + * the base registers. Each node has a register class it needs to be + * assigned to. Define p(B) to be the size of register class B, and + * q(B,C) to be the number of registers in B that the worst choice + * register in C could conflict with. Then, this system replaces the + * basic graph coloring test of "fewer edges from this node than there + * are registers" with "For this node of class B, the sum of q(B,C) + * for each neighbor node of class C is less than pB". + * + * A nice feature of the pq test is that q(B,C) can be computed once + * up front and stored in a 2-dimensional array, so that the cost of + * coloring a node is constant with the number of registers. We do + * this during ra_set_finalize(). + */ + +#include + +#include "ralloc.h" +#include "main/imports.h" +#include "main/macros.h" +#include "main/mtypes.h" +#include "util/bitset.h" +#include "register_allocate.h" + +#define NO_REG ~0U + +struct ra_reg { + BITSET_WORD *conflicts; + unsigned int *conflict_list; + unsigned int conflict_list_size; + unsigned int num_conflicts; +}; + +struct ra_regs { + struct ra_reg *regs; + unsigned int count; + + struct ra_class **classes; + unsigned int class_count; + + bool round_robin; +}; + +struct ra_class { + /** + * Bitset indicating which registers belong to this class. + * + * (If bit N is set, then register N belongs to this class.) + */ + BITSET_WORD *regs; + + /** + * p(B) in Runeson/Nyström paper. + * + * This is "how many regs are in the set." + */ + unsigned int p; + + /** + * q(B,C) (indexed by C, B is this register class) in + * Runeson/Nyström paper. This is "how many registers of B could + * the worst choice register from C conflict with". + */ + unsigned int *q; +}; + +struct ra_node { + /** @{ + * + * List of which nodes this node interferes with. This should be + * symmetric with the other node. + */ + BITSET_WORD *adjacency; + unsigned int *adjacency_list; + unsigned int adjacency_list_size; + unsigned int adjacency_count; + /** @} */ + + unsigned int class; + + /* Register, if assigned, or NO_REG. */ + unsigned int reg; + + /** + * Set when the node is in the trivially colorable stack. When + * set, the adjacency to this node is ignored, to implement the + * "remove the edge from the graph" in simplification without + * having to actually modify the adjacency_list. + */ + bool in_stack; + + /** + * The q total, as defined in the Runeson/Nyström paper, for all the + * interfering nodes not in the stack. + */ + unsigned int q_total; + + /* For an implementation that needs register spilling, this is the + * approximate cost of spilling this node. + */ + float spill_cost; +}; + +struct ra_graph { + struct ra_regs *regs; + /** + * the variables that need register allocation. + */ + struct ra_node *nodes; + unsigned int count; /**< count of nodes. */ + + unsigned int *stack; + unsigned int stack_count; + + /** + * Tracks the start of the set of optimistically-colored registers in the + * stack. + */ + unsigned int stack_optimistic_start; +}; + +/** + * Creates a set of registers for the allocator. + * + * mem_ctx is a ralloc context for the allocator. The reg set may be freed + * using ralloc_free(). + */ +struct ra_regs * +ra_alloc_reg_set(void *mem_ctx, unsigned int count, bool need_conflict_lists) +{ + unsigned int i; + struct ra_regs *regs; + + regs = rzalloc(mem_ctx, struct ra_regs); + regs->count = count; + regs->regs = rzalloc_array(regs, struct ra_reg, count); + + for (i = 0; i < count; i++) { + regs->regs[i].conflicts = rzalloc_array(regs->regs, BITSET_WORD, + BITSET_WORDS(count)); + BITSET_SET(regs->regs[i].conflicts, i); + + if (need_conflict_lists) { + regs->regs[i].conflict_list = ralloc_array(regs->regs, + unsigned int, 4); + regs->regs[i].conflict_list_size = 4; + regs->regs[i].conflict_list[0] = i; + } else { + regs->regs[i].conflict_list = NULL; + regs->regs[i].conflict_list_size = 0; + } + regs->regs[i].num_conflicts = 1; + } + + return regs; +} + +/** + * The register allocator by default prefers to allocate low register numbers, + * since it was written for hardware (gen4/5 Intel) that is limited in its + * multithreadedness by the number of registers used in a given shader. + * + * However, for hardware without that restriction, densely packed register + * allocation can put serious constraints on instruction scheduling. This + * function tells the allocator to rotate around the registers if possible as + * it allocates the nodes. + */ +void +ra_set_allocate_round_robin(struct ra_regs *regs) +{ + regs->round_robin = true; +} + +static void +ra_add_conflict_list(struct ra_regs *regs, unsigned int r1, unsigned int r2) +{ + struct ra_reg *reg1 = ®s->regs[r1]; + + if (reg1->conflict_list) { + if (reg1->conflict_list_size == reg1->num_conflicts) { + reg1->conflict_list_size *= 2; + reg1->conflict_list = reralloc(regs->regs, reg1->conflict_list, + unsigned int, reg1->conflict_list_size); + } + reg1->conflict_list[reg1->num_conflicts++] = r2; + } + BITSET_SET(reg1->conflicts, r2); +} + +void +ra_add_reg_conflict(struct ra_regs *regs, unsigned int r1, unsigned int r2) +{ + if (!BITSET_TEST(regs->regs[r1].conflicts, r2)) { + ra_add_conflict_list(regs, r1, r2); + ra_add_conflict_list(regs, r2, r1); + } +} + +/** + * Adds a conflict between base_reg and reg, and also between reg and + * anything that base_reg conflicts with. + * + * This can simplify code for setting up multiple register classes + * which are aggregates of some base hardware registers, compared to + * explicitly using ra_add_reg_conflict. + */ +void +ra_add_transitive_reg_conflict(struct ra_regs *regs, + unsigned int base_reg, unsigned int reg) +{ + unsigned int i; + + ra_add_reg_conflict(regs, reg, base_reg); + + for (i = 0; i < regs->regs[base_reg].num_conflicts; i++) { + ra_add_reg_conflict(regs, reg, regs->regs[base_reg].conflict_list[i]); + } +} + +/** + * Makes every conflict on the given register transitive. In other words, + * every register that conflicts with r will now conflict with every other + * register conflicting with r. + * + * This can simplify code for setting up multiple register classes + * which are aggregates of some base hardware registers, compared to + * explicitly using ra_add_reg_conflict. + */ +void +ra_make_reg_conflicts_transitive(struct ra_regs *regs, unsigned int r) +{ + struct ra_reg *reg = ®s->regs[r]; + BITSET_WORD tmp; + int c; + + BITSET_FOREACH_SET(c, tmp, reg->conflicts, regs->count) { + struct ra_reg *other = ®s->regs[c]; + unsigned i; + for (i = 0; i < BITSET_WORDS(regs->count); i++) + other->conflicts[i] |= reg->conflicts[i]; + } +} + +unsigned int +ra_alloc_reg_class(struct ra_regs *regs) +{ + struct ra_class *class; + + regs->classes = reralloc(regs->regs, regs->classes, struct ra_class *, + regs->class_count + 1); + + class = rzalloc(regs, struct ra_class); + regs->classes[regs->class_count] = class; + + class->regs = rzalloc_array(class, BITSET_WORD, BITSET_WORDS(regs->count)); + + return regs->class_count++; +} + +void +ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int r) +{ + struct ra_class *class = regs->classes[c]; + + BITSET_SET(class->regs, r); + class->p++; +} + +/** + * Returns true if the register belongs to the given class. + */ +static bool +reg_belongs_to_class(unsigned int r, struct ra_class *c) +{ + return BITSET_TEST(c->regs, r); +} + +/** + * Must be called after all conflicts and register classes have been + * set up and before the register set is used for allocation. + * To avoid costly q value computation, use the q_values paramater + * to pass precomputed q values to this function. + */ +void +ra_set_finalize(struct ra_regs *regs, unsigned int **q_values) +{ + unsigned int b, c; + + for (b = 0; b < regs->class_count; b++) { + regs->classes[b]->q = ralloc_array(regs, unsigned int, regs->class_count); + } + + if (q_values) { + for (b = 0; b < regs->class_count; b++) { + for (c = 0; c < regs->class_count; c++) { + regs->classes[b]->q[c] = q_values[b][c]; + } + } + } else { + /* Compute, for each class B and C, how many regs of B an + * allocation to C could conflict with. + */ + for (b = 0; b < regs->class_count; b++) { + for (c = 0; c < regs->class_count; c++) { + unsigned int rc; + int max_conflicts = 0; + + for (rc = 0; rc < regs->count; rc++) { + int conflicts = 0; + unsigned int i; + + if (!reg_belongs_to_class(rc, regs->classes[c])) + continue; + + for (i = 0; i < regs->regs[rc].num_conflicts; i++) { + unsigned int rb = regs->regs[rc].conflict_list[i]; + if (reg_belongs_to_class(rb, regs->classes[b])) + conflicts++; + } + max_conflicts = MAX2(max_conflicts, conflicts); + } + regs->classes[b]->q[c] = max_conflicts; + } + } + } + + for (b = 0; b < regs->count; b++) { + ralloc_free(regs->regs[b].conflict_list); + regs->regs[b].conflict_list = NULL; + } +} + +static void +ra_add_node_adjacency(struct ra_graph *g, unsigned int n1, unsigned int n2) +{ + BITSET_SET(g->nodes[n1].adjacency, n2); + + if (n1 != n2) { + int n1_class = g->nodes[n1].class; + int n2_class = g->nodes[n2].class; + g->nodes[n1].q_total += g->regs->classes[n1_class]->q[n2_class]; + } + + if (g->nodes[n1].adjacency_count >= + g->nodes[n1].adjacency_list_size) { + g->nodes[n1].adjacency_list_size *= 2; + g->nodes[n1].adjacency_list = reralloc(g, g->nodes[n1].adjacency_list, + unsigned int, + g->nodes[n1].adjacency_list_size); + } + + g->nodes[n1].adjacency_list[g->nodes[n1].adjacency_count] = n2; + g->nodes[n1].adjacency_count++; +} + +struct ra_graph * +ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count) +{ + struct ra_graph *g; + unsigned int i; + + g = rzalloc(NULL, struct ra_graph); + g->regs = regs; + g->nodes = rzalloc_array(g, struct ra_node, count); + g->count = count; + + g->stack = rzalloc_array(g, unsigned int, count); + + for (i = 0; i < count; i++) { + int bitset_count = BITSET_WORDS(count); + g->nodes[i].adjacency = rzalloc_array(g, BITSET_WORD, bitset_count); + + g->nodes[i].adjacency_list_size = 4; + g->nodes[i].adjacency_list = + ralloc_array(g, unsigned int, g->nodes[i].adjacency_list_size); + g->nodes[i].adjacency_count = 0; + g->nodes[i].q_total = 0; + + ra_add_node_adjacency(g, i, i); + g->nodes[i].reg = NO_REG; + } + + return g; +} + +void +ra_set_node_class(struct ra_graph *g, + unsigned int n, unsigned int class) +{ + g->nodes[n].class = class; +} + +void +ra_add_node_interference(struct ra_graph *g, + unsigned int n1, unsigned int n2) +{ + if (!BITSET_TEST(g->nodes[n1].adjacency, n2)) { + ra_add_node_adjacency(g, n1, n2); + ra_add_node_adjacency(g, n2, n1); + } +} + +static bool +pq_test(struct ra_graph *g, unsigned int n) +{ + int n_class = g->nodes[n].class; + + return g->nodes[n].q_total < g->regs->classes[n_class]->p; +} + +static void +decrement_q(struct ra_graph *g, unsigned int n) +{ + unsigned int i; + int n_class = g->nodes[n].class; + + for (i = 0; i < g->nodes[n].adjacency_count; i++) { + unsigned int n2 = g->nodes[n].adjacency_list[i]; + unsigned int n2_class = g->nodes[n2].class; + + if (n != n2 && !g->nodes[n2].in_stack) { + assert(g->nodes[n2].q_total >= g->regs->classes[n2_class]->q[n_class]); + g->nodes[n2].q_total -= g->regs->classes[n2_class]->q[n_class]; + } + } +} + +/** + * Simplifies the interference graph by pushing all + * trivially-colorable nodes into a stack of nodes to be colored, + * removing them from the graph, and rinsing and repeating. + * + * If we encounter a case where we can't push any nodes on the stack, then + * we optimistically choose a node and push it on the stack. We heuristically + * push the node with the lowest total q value, since it has the fewest + * neighbors and therefore is most likely to be allocated. + */ +static void +ra_simplify(struct ra_graph *g) +{ + bool progress = true; + unsigned int stack_optimistic_start = UINT_MAX; + int i; + + while (progress) { + unsigned int best_optimistic_node = ~0; + unsigned int lowest_q_total = ~0; + + progress = false; + + for (i = g->count - 1; i >= 0; i--) { + if (g->nodes[i].in_stack || g->nodes[i].reg != NO_REG) + continue; + + if (pq_test(g, i)) { + decrement_q(g, i); + g->stack[g->stack_count] = i; + g->stack_count++; + g->nodes[i].in_stack = true; + progress = true; + } else { + unsigned int new_q_total = g->nodes[i].q_total; + if (new_q_total < lowest_q_total) { + best_optimistic_node = i; + lowest_q_total = new_q_total; + } + } + } + + if (!progress && best_optimistic_node != ~0U) { + if (stack_optimistic_start == UINT_MAX) + stack_optimistic_start = g->stack_count; + + decrement_q(g, best_optimistic_node); + g->stack[g->stack_count] = best_optimistic_node; + g->stack_count++; + g->nodes[best_optimistic_node].in_stack = true; + progress = true; + } + } + + g->stack_optimistic_start = stack_optimistic_start; +} + +/** + * Pops nodes from the stack back into the graph, coloring them with + * registers as they go. + * + * If all nodes were trivially colorable, then this must succeed. If + * not (optimistic coloring), then it may return false; + */ +static bool +ra_select(struct ra_graph *g) +{ + int start_search_reg = 0; + + while (g->stack_count != 0) { + unsigned int i; + unsigned int ri; + unsigned int r = -1; + int n = g->stack[g->stack_count - 1]; + struct ra_class *c = g->regs->classes[g->nodes[n].class]; + + /* Find the lowest-numbered reg which is not used by a member + * of the graph adjacent to us. + */ + for (ri = 0; ri < g->regs->count; ri++) { + r = (start_search_reg + ri) % g->regs->count; + if (!reg_belongs_to_class(r, c)) + continue; + + /* Check if any of our neighbors conflict with this register choice. */ + for (i = 0; i < g->nodes[n].adjacency_count; i++) { + unsigned int n2 = g->nodes[n].adjacency_list[i]; + + if (!g->nodes[n2].in_stack && + BITSET_TEST(g->regs->regs[r].conflicts, g->nodes[n2].reg)) { + break; + } + } + if (i == g->nodes[n].adjacency_count) + break; + } + + /* set this to false even if we return here so that + * ra_get_best_spill_node() considers this node later. + */ + g->nodes[n].in_stack = false; + + if (ri == g->regs->count) + return false; + + g->nodes[n].reg = r; + g->stack_count--; + + /* Rotate the starting point except for any nodes above the lowest + * optimistically colorable node. The likelihood that we will succeed + * at allocating optimistically colorable nodes is highly dependent on + * the way that the previous nodes popped off the stack are laid out. + * The round-robin strategy increases the fragmentation of the register + * file and decreases the number of nearby nodes assigned to the same + * color, what increases the likelihood of spilling with respect to the + * dense packing strategy. + */ + if (g->regs->round_robin && + g->stack_count - 1 <= g->stack_optimistic_start) + start_search_reg = r + 1; + } + + return true; +} + +bool +ra_allocate(struct ra_graph *g) +{ + ra_simplify(g); + return ra_select(g); +} + +unsigned int +ra_get_node_reg(struct ra_graph *g, unsigned int n) +{ + return g->nodes[n].reg; +} + +/** + * Forces a node to a specific register. This can be used to avoid + * creating a register class containing one node when handling data + * that must live in a fixed location and is known to not conflict + * with other forced register assignment (as is common with shader + * input data). These nodes do not end up in the stack during + * ra_simplify(), and thus at ra_select() time it is as if they were + * the first popped off the stack and assigned their fixed locations. + * Nodes that use this function do not need to be assigned a register + * class. + * + * Must be called before ra_simplify(). + */ +void +ra_set_node_reg(struct ra_graph *g, unsigned int n, unsigned int reg) +{ + g->nodes[n].reg = reg; + g->nodes[n].in_stack = false; +} + +static float +ra_get_spill_benefit(struct ra_graph *g, unsigned int n) +{ + unsigned int j; + float benefit = 0; + int n_class = g->nodes[n].class; + + /* Define the benefit of eliminating an interference between n, n2 + * through spilling as q(C, B) / p(C). This is similar to the + * "count number of edges" approach of traditional graph coloring, + * but takes classes into account. + */ + for (j = 0; j < g->nodes[n].adjacency_count; j++) { + unsigned int n2 = g->nodes[n].adjacency_list[j]; + if (n != n2) { + unsigned int n2_class = g->nodes[n2].class; + benefit += ((float)g->regs->classes[n_class]->q[n2_class] / + g->regs->classes[n_class]->p); + } + } + + return benefit; +} + +/** + * Returns a node number to be spilled according to the cost/benefit using + * the pq test, or -1 if there are no spillable nodes. + */ +int +ra_get_best_spill_node(struct ra_graph *g) +{ + unsigned int best_node = -1; + float best_benefit = 0.0; + unsigned int n; + + /* Consider any nodes that we colored successfully or the node we failed to + * color for spilling. When we failed to color a node in ra_select(), we + * only considered these nodes, so spilling any other ones would not result + * in us making progress. + */ + for (n = 0; n < g->count; n++) { + float cost = g->nodes[n].spill_cost; + float benefit; + + if (cost <= 0.0f) + continue; + + if (g->nodes[n].in_stack) + continue; + + benefit = ra_get_spill_benefit(g, n); + + if (benefit / cost > best_benefit) { + best_benefit = benefit / cost; + best_node = n; + } + } + + return best_node; +} + +/** + * Only nodes with a spill cost set (cost != 0.0) will be considered + * for register spilling. + */ +void +ra_set_node_spill_cost(struct ra_graph *g, unsigned int n, float cost) +{ + g->nodes[n].spill_cost = cost; +} diff --git a/lib/mesa/src/util/register_allocate.h b/lib/mesa/src/util/register_allocate.h new file mode 100644 index 000000000..628d2bbbc --- /dev/null +++ b/lib/mesa/src/util/register_allocate.h @@ -0,0 +1,91 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct ra_class; +struct ra_regs; + +/* @{ + * Register set setup. + * + * This should be done once at backend initializaion, as + * ra_set_finalize is O(r^2*c^2). The registers may be virtual + * registers, such as aligned register pairs that conflict with the + * two real registers from which they are composed. + */ +struct ra_regs *ra_alloc_reg_set(void *mem_ctx, unsigned int count, + bool need_conflict_lists); +void ra_set_allocate_round_robin(struct ra_regs *regs); +unsigned int ra_alloc_reg_class(struct ra_regs *regs); +void ra_add_reg_conflict(struct ra_regs *regs, + unsigned int r1, unsigned int r2); +void ra_add_transitive_reg_conflict(struct ra_regs *regs, + unsigned int base_reg, unsigned int reg); +void ra_make_reg_conflicts_transitive(struct ra_regs *regs, unsigned int reg); +void ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int reg); +void ra_set_num_conflicts(struct ra_regs *regs, unsigned int class_a, + unsigned int class_b, unsigned int num_conflicts); +void ra_set_finalize(struct ra_regs *regs, unsigned int **conflicts); +/** @} */ + +/** @{ Interference graph setup. + * + * Each interference graph node is a virtual variable in the IL. It + * is up to the user to ra_set_node_class() for the virtual variable, + * and compute live ranges and ra_node_interfere() between conflicting + * live ranges. Note that an interference *must not* be added between + * two nodes if their classes haven't been assigned yet. The user + * should set the class of each node before building the interference + * graph. + */ +struct ra_graph *ra_alloc_interference_graph(struct ra_regs *regs, + unsigned int count); +void ra_set_node_class(struct ra_graph *g, unsigned int n, unsigned int c); +void ra_add_node_interference(struct ra_graph *g, + unsigned int n1, unsigned int n2); +/** @} */ + +/** @{ Graph-coloring register allocation */ +bool ra_allocate(struct ra_graph *g); + +unsigned int ra_get_node_reg(struct ra_graph *g, unsigned int n); +void ra_set_node_reg(struct ra_graph * g, unsigned int n, unsigned int reg); +void ra_set_node_spill_cost(struct ra_graph *g, unsigned int n, float cost); +int ra_get_best_spill_node(struct ra_graph *g); +/** @} */ + + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/lib/mesa/src/util/rgtc.c b/lib/mesa/src/util/rgtc.c new file mode 100644 index 000000000..6886ac071 --- /dev/null +++ b/lib/mesa/src/util/rgtc.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2011 Red Hat Inc. + * + * block compression parts are: + * Copyright (C) 2004 Roland Scheidegger All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: + * Dave Airlie + */ + +#include +#include "macros.h" + +#include "rgtc.h" + +#define RGTC_DEBUG 0 + +#define TAG(x) util_format_unsigned_##x + +#define TYPE unsigned char +#define T_MIN 0 +#define T_MAX 0xff + +#include "texcompress_rgtc_tmp.h" + +#undef TAG +#undef TYPE +#undef T_MIN +#undef T_MAX + +#define TAG(x) util_format_signed_##x +#define TYPE signed char +#define T_MIN (signed char)-128 +#define T_MAX (signed char)127 + +#include "texcompress_rgtc_tmp.h" + +#undef TAG +#undef TYPE +#undef T_MIN +#undef T_MAX + diff --git a/lib/mesa/src/util/rgtc.h b/lib/mesa/src/util/rgtc.h new file mode 100644 index 000000000..6bba9f2ec --- /dev/null +++ b/lib/mesa/src/util/rgtc.h @@ -0,0 +1,39 @@ +/* + * Copyright © 2014 Red Hat + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#ifndef _RGTC_H +#define _RGTC_H + +void util_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const unsigned char *pixdata, + unsigned i, unsigned j, unsigned char *value, unsigned comps); + +void util_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const signed char *pixdata, + unsigned i, unsigned j, signed char *value, unsigned comps); + +void util_format_unsigned_encode_rgtc_ubyte(unsigned char *blkaddr, unsigned char srccolors[4][4], + int numxpixels, int numypixels); + +void util_format_signed_encode_rgtc_ubyte(signed char *blkaddr, signed char srccolors[4][4], + int numxpixels, int numypixels); +#endif /* _RGTC_H */ diff --git a/lib/mesa/src/util/roundeven_test.c b/lib/mesa/src/util/roundeven_test.c new file mode 100644 index 000000000..7526db1f3 --- /dev/null +++ b/lib/mesa/src/util/roundeven_test.c @@ -0,0 +1,140 @@ +/* + * Copyright © 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "macros.h" +#include "rounding.h" + +int main(int argc, char *argv[]) +{ + const struct { + float input, expected; + } float_data[] = { + { 0.0, 0.0 }, + { nextafterf(0.5, 0.0), 0.0 }, + { 0.5, 0.0 }, + { nextafterf(0.5, 1.0), 1.0 }, + { 1.0, 1.0 }, + { nextafterf(1.5, 1.0), 1.0 }, + { 1.5, 2.0 }, + { nextafterf(1.5, 2.0), 2.0 }, + { 2.0, 2.0 }, + { nextafterf(2.5, 2.0), 2.0 }, + { 2.5, 2.0 }, + { nextafterf(2.5, 3.0), 3.0 }, + }; + + const struct { + double input, expected; + } double_data[] = { + { 0.0, 0.0 }, + { nextafter(0.5, 0.0), 0.0 }, + { 0.5, 0.0 }, + { nextafter(0.5, 1.0), 1.0 }, + { 1.0, 1.0 }, + { nextafter(1.5, 1.0), 1.0 }, + { 1.5, 2.0 }, + { nextafter(1.5, 2.0), 2.0 }, + { 2.0, 2.0 }, + { nextafter(2.5, 2.0), 2.0 }, + { 2.5, 2.0 }, + { nextafter(2.5, 3.0), 3.0 }, + }; + + bool failed = false; + int i; + + for (i = 0; i < ARRAY_SIZE(float_data); i++) { + float output = _mesa_roundevenf(float_data[i].input); + if (memcmp(&float_data[i].expected, &output, sizeof(float))) { + fprintf(stderr, "%d float: expected %f (%a) from " + "_mesa_roundevenf(%f (%a)) but got %f (%a)\n", + i, + float_data[i].expected, + float_data[i].expected, + float_data[i].input, + float_data[i].input, + output, + output); + failed = true; + } + } + + /* Test negated values */ + for (i = 0; i < ARRAY_SIZE(float_data); i++) { + float output = _mesa_roundevenf(-float_data[i].input); + float negated_expected = -float_data[i].expected; + if (memcmp(&negated_expected, &output, sizeof(float))) { + fprintf(stderr, "%d float: expected %f (%a) from " + "_mesa_roundevenf(%f (%a)) but got %f (%a)\n", + i, + negated_expected, + negated_expected, + -float_data[i].input, + -float_data[i].input, + output, + output); + failed = true; + } + } + + for (i = 0; i < ARRAY_SIZE(double_data); i++) { + double output = _mesa_roundeven(double_data[i].input); + if (memcmp(&double_data[i].expected, &output, sizeof(double))) { + fprintf(stderr, "%d double: expected %f (%a) from " + "_mesa_roundeven(%f (%a)) but got %f (%a)\n", + i, + double_data[i].expected, + double_data[i].expected, + double_data[i].input, + double_data[i].input, + output, + output); + failed = true; + } + } + + /* Test negated values */ + for (i = 0; i < ARRAY_SIZE(double_data); i++) { + double output = _mesa_roundeven(-double_data[i].input); + double negated_expected = -double_data[i].expected; + if (memcmp(&negated_expected, &output, sizeof(double))) { + fprintf(stderr, "%d double: expected %f (%a) from " + "_mesa_roundeven(%f (%a)) but got %f (%a)\n", + i, + negated_expected, + negated_expected, + -double_data[i].input, + -double_data[i].input, + output, + output); + failed = true; + } + } + + return failed; +} diff --git a/lib/mesa/src/util/rounding.h b/lib/mesa/src/util/rounding.h new file mode 100644 index 000000000..afb38fbdb --- /dev/null +++ b/lib/mesa/src/util/rounding.h @@ -0,0 +1,131 @@ +/* + * Copyright © 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _ROUNDING_H +#define _ROUNDING_H + +#include "c99_math.h" + +#include +#include + +#ifdef __x86_64__ +#include +#include +#endif + +#ifdef __SSE4_1__ +#include +#endif + +/* The C standard library has functions round()/rint()/nearbyint() that round + * their arguments according to the rounding mode set in the floating-point + * control register. While there are trunc()/ceil()/floor() functions that do + * a specific operation without modifying the rounding mode, there is no + * roundeven() in any version of C. + * + * Technical Specification 18661 (ISO/IEC TS 18661-1:2014) adds roundeven(), + * but it's unfortunately not implemented by glibc. + * + * This implementation differs in that it does not raise the inexact exception. + * + * We use rint() to implement these functions, with the assumption that the + * floating-point rounding mode has not been changed from the default Round + * to Nearest. + */ + +/** + * \brief Rounds \c x to the nearest integer, with ties to the even integer. + */ +static inline float +_mesa_roundevenf(float x) +{ +#ifdef __SSE4_1__ + float ret; + __m128 m = _mm_load_ss(&x); + m = _mm_round_ss(m, m, _MM_FROUND_CUR_DIRECTION | _MM_FROUND_NO_EXC); + _mm_store_ss(&ret, m); + return ret; +#else + return rintf(x); +#endif +} + +/** + * \brief Rounds \c x to the nearest integer, with ties to the even integer. + */ +static inline double +_mesa_roundeven(double x) +{ +#ifdef __SSE4_1__ + double ret; + __m128d m = _mm_load_sd(&x); + m = _mm_round_sd(m, m, _MM_FROUND_CUR_DIRECTION | _MM_FROUND_NO_EXC); + _mm_store_sd(&ret, m); + return ret; +#else + return rint(x); +#endif +} + +/** + * \brief Rounds \c x to the nearest integer, with ties to the even integer, + * and returns the value as a long int. + */ +static inline long +_mesa_lroundevenf(float x) +{ +#ifdef __x86_64__ +#if LONG_MAX == INT64_MAX + return _mm_cvtss_si64(_mm_load_ss(&x)); +#elif LONG_MAX == INT32_MAX + return _mm_cvtss_si32(_mm_load_ss(&x)); +#else +#error "Unsupported long size" +#endif +#else + return lrintf(x); +#endif +} + +/** + * \brief Rounds \c x to the nearest integer, with ties to the even integer, + * and returns the value as a long int. + */ +static inline long +_mesa_lroundeven(double x) +{ +#ifdef __x86_64__ +#if LONG_MAX == INT64_MAX + return _mm_cvtsd_si64(_mm_load_sd(&x)); +#elif LONG_MAX == INT32_MAX + return _mm_cvtsd_si32(_mm_load_sd(&x)); +#else +#error "Unsupported long size" +#endif +#else + return lrint(x); +#endif +} + +#endif diff --git a/lib/mesa/src/util/set.c b/lib/mesa/src/util/set.c new file mode 100644 index 000000000..f01f8699a --- /dev/null +++ b/lib/mesa/src/util/set.c @@ -0,0 +1,391 @@ +/* + * Copyright © 2009-2012 Intel Corporation + * Copyright © 1988-2004 Keith Packard and Bart Massey. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors + * or their institutions shall not be used in advertising or + * otherwise to promote the sale, use or other dealings in this + * Software without prior written authorization from the + * authors. + * + * Authors: + * Eric Anholt + * Keith Packard + */ + +#include +#include + +#include "macros.h" +#include "ralloc.h" +#include "set.h" + +/* + * From Knuth -- a good choice for hash/rehash values is p, p-2 where + * p and p-2 are both prime. These tables are sized to have an extra 10% + * free to avoid exponential performance degradation as the hash table fills + */ + +uint32_t deleted_key_value; +const void *deleted_key = &deleted_key_value; + +static const struct { + uint32_t max_entries, size, rehash; +} hash_sizes[] = { + { 2, 5, 3 }, + { 4, 7, 5 }, + { 8, 13, 11 }, + { 16, 19, 17 }, + { 32, 43, 41 }, + { 64, 73, 71 }, + { 128, 151, 149 }, + { 256, 283, 281 }, + { 512, 571, 569 }, + { 1024, 1153, 1151 }, + { 2048, 2269, 2267 }, + { 4096, 4519, 4517 }, + { 8192, 9013, 9011 }, + { 16384, 18043, 18041 }, + { 32768, 36109, 36107 }, + { 65536, 72091, 72089 }, + { 131072, 144409, 144407 }, + { 262144, 288361, 288359 }, + { 524288, 576883, 576881 }, + { 1048576, 1153459, 1153457 }, + { 2097152, 2307163, 2307161 }, + { 4194304, 4613893, 4613891 }, + { 8388608, 9227641, 9227639 }, + { 16777216, 18455029, 18455027 }, + { 33554432, 36911011, 36911009 }, + { 67108864, 73819861, 73819859 }, + { 134217728, 147639589, 147639587 }, + { 268435456, 295279081, 295279079 }, + { 536870912, 590559793, 590559791 }, + { 1073741824, 1181116273, 1181116271 }, + { 2147483648ul, 2362232233ul, 2362232231ul } +}; + +static int +entry_is_free(struct set_entry *entry) +{ + return entry->key == NULL; +} + +static int +entry_is_deleted(struct set_entry *entry) +{ + return entry->key == deleted_key; +} + +static int +entry_is_present(struct set_entry *entry) +{ + return entry->key != NULL && entry->key != deleted_key; +} + +struct set * +_mesa_set_create(void *mem_ctx, + uint32_t (*key_hash_function)(const void *key), + bool (*key_equals_function)(const void *a, + const void *b)) +{ + struct set *ht; + + ht = ralloc(mem_ctx, struct set); + if (ht == NULL) + return NULL; + + ht->size_index = 0; + ht->size = hash_sizes[ht->size_index].size; + ht->rehash = hash_sizes[ht->size_index].rehash; + ht->max_entries = hash_sizes[ht->size_index].max_entries; + ht->key_hash_function = key_hash_function; + ht->key_equals_function = key_equals_function; + ht->table = rzalloc_array(ht, struct set_entry, ht->size); + ht->entries = 0; + ht->deleted_entries = 0; + + if (ht->table == NULL) { + ralloc_free(ht); + return NULL; + } + + return ht; +} + +/** + * Frees the given set. + * + * If delete_function is passed, it gets called on each entry present before + * freeing. + */ +void +_mesa_set_destroy(struct set *ht, void (*delete_function)(struct set_entry *entry)) +{ + if (!ht) + return; + + if (delete_function) { + struct set_entry *entry; + + set_foreach (ht, entry) { + delete_function(entry); + } + } + ralloc_free(ht->table); + ralloc_free(ht); +} + +/** + * Finds a set entry with the given key and hash of that key. + * + * Returns NULL if no entry is found. + */ +static struct set_entry * +set_search(const struct set *ht, uint32_t hash, const void *key) +{ + uint32_t hash_address; + + hash_address = hash % ht->size; + do { + uint32_t double_hash; + + struct set_entry *entry = ht->table + hash_address; + + if (entry_is_free(entry)) { + return NULL; + } else if (entry_is_present(entry) && entry->hash == hash) { + if (ht->key_equals_function(key, entry->key)) { + return entry; + } + } + + double_hash = 1 + hash % ht->rehash; + + hash_address = (hash_address + double_hash) % ht->size; + } while (hash_address != hash % ht->size); + + return NULL; +} + +struct set_entry * +_mesa_set_search(const struct set *set, const void *key) +{ + assert(set->key_hash_function); + return set_search(set, set->key_hash_function(key), key); +} + +struct set_entry * +_mesa_set_search_pre_hashed(const struct set *set, uint32_t hash, + const void *key) +{ + assert(set->key_hash_function == NULL || + hash == set->key_hash_function(key)); + return set_search(set, hash, key); +} + +static struct set_entry * +set_add(struct set *ht, uint32_t hash, const void *key); + +static void +set_rehash(struct set *ht, unsigned new_size_index) +{ + struct set old_ht; + struct set_entry *table, *entry; + + if (new_size_index >= ARRAY_SIZE(hash_sizes)) + return; + + table = rzalloc_array(ht, struct set_entry, + hash_sizes[new_size_index].size); + if (table == NULL) + return; + + old_ht = *ht; + + ht->table = table; + ht->size_index = new_size_index; + ht->size = hash_sizes[ht->size_index].size; + ht->rehash = hash_sizes[ht->size_index].rehash; + ht->max_entries = hash_sizes[ht->size_index].max_entries; + ht->entries = 0; + ht->deleted_entries = 0; + + for (entry = old_ht.table; + entry != old_ht.table + old_ht.size; + entry++) { + if (entry_is_present(entry)) { + set_add(ht, entry->hash, entry->key); + } + } + + ralloc_free(old_ht.table); +} + +/** + * Inserts the key with the given hash into the table. + * + * Note that insertion may rearrange the table on a resize or rehash, + * so previously found hash_entries are no longer valid after this function. + */ +static struct set_entry * +set_add(struct set *ht, uint32_t hash, const void *key) +{ + uint32_t hash_address; + struct set_entry *available_entry = NULL; + + if (ht->entries >= ht->max_entries) { + set_rehash(ht, ht->size_index + 1); + } else if (ht->deleted_entries + ht->entries >= ht->max_entries) { + set_rehash(ht, ht->size_index); + } + + hash_address = hash % ht->size; + do { + struct set_entry *entry = ht->table + hash_address; + uint32_t double_hash; + + if (!entry_is_present(entry)) { + /* Stash the first available entry we find */ + if (available_entry == NULL) + available_entry = entry; + if (entry_is_free(entry)) + break; + } + + /* Implement replacement when another insert happens + * with a matching key. This is a relatively common + * feature of hash tables, with the alternative + * generally being "insert the new value as well, and + * return it first when the key is searched for". + * + * Note that the hash table doesn't have a delete callback. + * If freeing of old keys is required to avoid memory leaks, + * perform a search before inserting. + */ + if (entry->hash == hash && + ht->key_equals_function(key, entry->key)) { + entry->key = key; + return entry; + } + + double_hash = 1 + hash % ht->rehash; + + hash_address = (hash_address + double_hash) % ht->size; + } while (hash_address != hash % ht->size); + + if (available_entry) { + if (entry_is_deleted(available_entry)) + ht->deleted_entries--; + available_entry->hash = hash; + available_entry->key = key; + ht->entries++; + return available_entry; + } + + /* We could hit here if a required resize failed. An unchecked-malloc + * application could ignore this result. + */ + return NULL; +} + +struct set_entry * +_mesa_set_add(struct set *set, const void *key) +{ + assert(set->key_hash_function); + return set_add(set, set->key_hash_function(key), key); +} + +struct set_entry * +_mesa_set_add_pre_hashed(struct set *set, uint32_t hash, const void *key) +{ + assert(set->key_hash_function == NULL || + hash == set->key_hash_function(key)); + return set_add(set, hash, key); +} + +/** + * This function deletes the given hash table entry. + * + * Note that deletion doesn't otherwise modify the table, so an iteration over + * the table deleting entries is safe. + */ +void +_mesa_set_remove(struct set *ht, struct set_entry *entry) +{ + if (!entry) + return; + + entry->key = deleted_key; + ht->entries--; + ht->deleted_entries++; +} + +/** + * This function is an iterator over the hash table. + * + * Pass in NULL for the first entry, as in the start of a for loop. Note that + * an iteration over the table is O(table_size) not O(entries). + */ +struct set_entry * +_mesa_set_next_entry(const struct set *ht, struct set_entry *entry) +{ + if (entry == NULL) + entry = ht->table; + else + entry = entry + 1; + + for (; entry != ht->table + ht->size; entry++) { + if (entry_is_present(entry)) { + return entry; + } + } + + return NULL; +} + +struct set_entry * +_mesa_set_random_entry(struct set *ht, + int (*predicate)(struct set_entry *entry)) +{ + struct set_entry *entry; + uint32_t i = rand() % ht->size; + + if (ht->entries == 0) + return NULL; + + for (entry = ht->table + i; entry != ht->table + ht->size; entry++) { + if (entry_is_present(entry) && + (!predicate || predicate(entry))) { + return entry; + } + } + + for (entry = ht->table; entry != ht->table + i; entry++) { + if (entry_is_present(entry) && + (!predicate || predicate(entry))) { + return entry; + } + } + + return NULL; +} diff --git a/lib/mesa/src/util/set.h b/lib/mesa/src/util/set.h new file mode 100644 index 000000000..9acd2c28c --- /dev/null +++ b/lib/mesa/src/util/set.h @@ -0,0 +1,100 @@ +/* + * Copyright © 2009-2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +#ifndef _SET_H +#define _SET_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct set_entry { + uint32_t hash; + const void *key; +}; + +struct set { + void *mem_ctx; + struct set_entry *table; + uint32_t (*key_hash_function)(const void *key); + bool (*key_equals_function)(const void *a, const void *b); + uint32_t size; + uint32_t rehash; + uint32_t max_entries; + uint32_t size_index; + uint32_t entries; + uint32_t deleted_entries; +}; + +struct set * +_mesa_set_create(void *mem_ctx, + uint32_t (*key_hash_function)(const void *key), + bool (*key_equals_function)(const void *a, + const void *b)); +void +_mesa_set_destroy(struct set *set, + void (*delete_function)(struct set_entry *entry)); + +struct set_entry * +_mesa_set_add(struct set *set, const void *key); +struct set_entry * +_mesa_set_add_pre_hashed(struct set *set, uint32_t hash, const void *key); + +struct set_entry * +_mesa_set_search(const struct set *set, const void *key); +struct set_entry * +_mesa_set_search_pre_hashed(const struct set *set, uint32_t hash, + const void *key); + +void +_mesa_set_remove(struct set *set, struct set_entry *entry); + +struct set_entry * +_mesa_set_next_entry(const struct set *set, struct set_entry *entry); + +struct set_entry * +_mesa_set_random_entry(struct set *set, + int (*predicate)(struct set_entry *entry)); + +/** + * This foreach function is safe against deletion, but not against + * insertion (which may rehash the set, making entry a dangling + * pointer). + */ +#define set_foreach(set, entry) \ + for (entry = _mesa_set_next_entry(set, NULL); \ + entry != NULL; \ + entry = _mesa_set_next_entry(set, entry)) + +#ifdef __cplusplus +} /* extern C */ +#endif + +#endif /* _SET_H */ diff --git a/lib/mesa/src/util/simple_list.h b/lib/mesa/src/util/simple_list.h new file mode 100644 index 000000000..5f261612a --- /dev/null +++ b/lib/mesa/src/util/simple_list.h @@ -0,0 +1,211 @@ +/** + * \file simple_list.h + * Simple macros for type-safe, intrusive lists. + * + * Intended to work with a list sentinal which is created as an empty + * list. Insert & delete are O(1). + * + * \author + * (C) 1997, Keith Whitwell + */ + +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef _SIMPLE_LIST_H +#define _SIMPLE_LIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct simple_node { + struct simple_node *next; + struct simple_node *prev; +}; + +/** + * Remove an element from list. + * + * \param elem element to remove. + */ +#define remove_from_list(elem) \ +do { \ + (elem)->next->prev = (elem)->prev; \ + (elem)->prev->next = (elem)->next; \ + make_empty_list(elem); \ +} while (0) + +/** + * Insert an element to the list head. + * + * \param list list. + * \param elem element to insert. + */ +#define insert_at_head(list, elem) \ +do { \ + (elem)->prev = list; \ + (elem)->next = (list)->next; \ + (list)->next->prev = elem; \ + (list)->next = elem; \ +} while(0) + +/** + * Insert an element to the list tail. + * + * \param list list. + * \param elem element to insert. + */ +#define insert_at_tail(list, elem) \ +do { \ + (elem)->next = list; \ + (elem)->prev = (list)->prev; \ + (list)->prev->next = elem; \ + (list)->prev = elem; \ +} while(0) + +/** + * Move an element to the list head. + * + * \param list list. + * \param elem element to move. + */ +#define move_to_head(list, elem) \ +do { \ + remove_from_list(elem); \ + insert_at_head(list, elem); \ +} while (0) + +/** + * Move an element to the list tail. + * + * \param list list. + * \param elem element to move. + */ +#define move_to_tail(list, elem) \ +do { \ + remove_from_list(elem); \ + insert_at_tail(list, elem); \ +} while (0) + +/** + * Make a empty list empty. + * + * \param sentinal list (sentinal element). + */ +#define make_empty_list(sentinal) \ +do { \ + (sentinal)->next = sentinal; \ + (sentinal)->prev = sentinal; \ +} while (0) + +/** + * Get list first element. + * + * \param list list. + * + * \return pointer to first element. + */ +#define first_elem(list) ((list)->next) + +/** + * Get list last element. + * + * \param list list. + * + * \return pointer to last element. + */ +#define last_elem(list) ((list)->prev) + +/** + * Get next element. + * + * \param elem element. + * + * \return pointer to next element. + */ +#define next_elem(elem) ((elem)->next) + +/** + * Get previous element. + * + * \param elem element. + * + * \return pointer to previous element. + */ +#define prev_elem(elem) ((elem)->prev) + +/** + * Test whether element is at end of the list. + * + * \param list list. + * \param elem element. + * + * \return non-zero if element is at end of list, or zero otherwise. + */ +#define at_end(list, elem) ((elem) == (list)) + +/** + * Test if a list is empty. + * + * \param list list. + * + * \return non-zero if list empty, or zero otherwise. + */ +#define is_empty_list(list) ((list)->next == (list)) + +/** + * Walk through the elements of a list. + * + * \param ptr pointer to the current element. + * \param list list. + * + * \note It should be followed by a { } block or a single statement, as in a \c + * for loop. + */ +#define foreach(ptr, list) \ + for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next ) + +/** + * Walk through the elements of a list. + * + * Same as #foreach but lets you unlink the current value during a list + * traversal. Useful for freeing a list, element by element. + * + * \param ptr pointer to the current element. + * \param t temporary pointer. + * \param list list. + * + * \note It should be followed by a { } block or a single statement, as in a \c + * for loop. + */ +#define foreach_s(ptr, t, list) \ + for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/mesa/src/util/strtod.c b/lib/mesa/src/util/strtod.c new file mode 100644 index 000000000..ea7d395e2 --- /dev/null +++ b/lib/mesa/src/util/strtod.c @@ -0,0 +1,85 @@ +/* + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include + +#ifdef _GNU_SOURCE +#include +#ifdef HAVE_XLOCALE_H +#include +static locale_t loc; +#endif +#endif + +#include "strtod.h" + + +void +_mesa_locale_init(void) +{ +#if defined(_GNU_SOURCE) && defined(HAVE_XLOCALE_H) + loc = newlocale(LC_CTYPE_MASK, "C", NULL); +#endif +} + +void +_mesa_locale_fini(void) +{ +#if defined(_GNU_SOURCE) && defined(HAVE_XLOCALE_H) + freelocale(loc); +#endif +} + +/** + * Wrapper around strtod which uses the "C" locale so the decimal + * point is always '.' + */ +double +_mesa_strtod(const char *s, char **end) +{ +#if defined(_GNU_SOURCE) && defined(HAVE_XLOCALE_H) + return strtod_l(s, end, loc); +#else + return strtod(s, end); +#endif +} + + +/** + * Wrapper around strtof which uses the "C" locale so the decimal + * point is always '.' + */ +float +_mesa_strtof(const char *s, char **end) +{ +#if defined(_GNU_SOURCE) && defined(HAVE_XLOCALE_H) + return strtof_l(s, end, loc); +#elif defined(HAVE_STRTOF) + return strtof(s, end); +#else + return (float) strtod(s, end); +#endif +} diff --git a/lib/mesa/src/util/strtod.h b/lib/mesa/src/util/strtod.h new file mode 100644 index 000000000..60e15cfa0 --- /dev/null +++ b/lib/mesa/src/util/strtod.h @@ -0,0 +1,52 @@ +/* + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef STRTOD_H +#define STRTOD_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern void +_mesa_locale_init(void); + +extern void +_mesa_locale_fini(void); + +extern double +_mesa_strtod(const char *s, char **end); + +extern float +_mesa_strtof(const char *s, char **end); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/lib/mesa/src/util/tests/hash_table/Makefile.am b/lib/mesa/src/util/tests/hash_table/Makefile.am new file mode 100644 index 000000000..04a77e30d --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/Makefile.am @@ -0,0 +1,44 @@ +# Copyright © 2009 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/util \ + $(DEFINES) + +LDADD = \ + $(top_builddir)/src/util/libmesautil.la \ + $(PTHREAD_LIBS) \ + $(DLOPEN_LIBS) + +TESTS = \ + collision \ + delete_and_lookup \ + delete_management \ + destroy_callback \ + insert_and_lookup \ + insert_many \ + null_destroy \ + random_entry \ + remove_null \ + replacement \ + $() + +check_PROGRAMS = $(TESTS) diff --git a/lib/mesa/src/util/tests/hash_table/Makefile.in b/lib/mesa/src/util/tests/hash_table/Makefile.in new file mode 100644 index 000000000..d70de52ce --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/Makefile.in @@ -0,0 +1,1326 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright © 2009 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +TESTS = collision$(EXEEXT) delete_and_lookup$(EXEEXT) \ + delete_management$(EXEEXT) destroy_callback$(EXEEXT) \ + insert_and_lookup$(EXEEXT) insert_many$(EXEEXT) \ + null_destroy$(EXEEXT) random_entry$(EXEEXT) \ + remove_null$(EXEEXT) replacement$(EXEEXT) +check_PROGRAMS = $(am__EXEEXT_1) +subdir = src/util/tests/hash_table +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_gnu_make.m4 \ + $(top_srcdir)/m4/ax_check_python_mako_module.m4 \ + $(top_srcdir)/m4/ax_gcc_builtin.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_prog_bison.m4 \ + $(top_srcdir)/m4/ax_prog_flex.m4 \ + $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/VERSION $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__EXEEXT_1 = collision$(EXEEXT) delete_and_lookup$(EXEEXT) \ + delete_management$(EXEEXT) destroy_callback$(EXEEXT) \ + insert_and_lookup$(EXEEXT) insert_many$(EXEEXT) \ + null_destroy$(EXEEXT) random_entry$(EXEEXT) \ + remove_null$(EXEEXT) replacement$(EXEEXT) +collision_SOURCES = collision.c +collision_OBJECTS = collision.$(OBJEXT) +collision_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +collision_DEPENDENCIES = $(top_builddir)/src/util/libmesautil.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +delete_and_lookup_SOURCES = delete_and_lookup.c +delete_and_lookup_OBJECTS = delete_and_lookup.$(OBJEXT) +delete_and_lookup_LDADD = $(LDADD) +delete_and_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libmesautil.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +delete_management_SOURCES = delete_management.c +delete_management_OBJECTS = delete_management.$(OBJEXT) +delete_management_LDADD = $(LDADD) +delete_management_DEPENDENCIES = \ + $(top_builddir)/src/util/libmesautil.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +destroy_callback_SOURCES = destroy_callback.c +destroy_callback_OBJECTS = destroy_callback.$(OBJEXT) +destroy_callback_LDADD = $(LDADD) +destroy_callback_DEPENDENCIES = \ + $(top_builddir)/src/util/libmesautil.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +insert_and_lookup_SOURCES = insert_and_lookup.c +insert_and_lookup_OBJECTS = insert_and_lookup.$(OBJEXT) +insert_and_lookup_LDADD = $(LDADD) +insert_and_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libmesautil.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +insert_many_SOURCES = insert_many.c +insert_many_OBJECTS = insert_many.$(OBJEXT) +insert_many_LDADD = $(LDADD) +insert_many_DEPENDENCIES = $(top_builddir)/src/util/libmesautil.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +null_destroy_SOURCES = null_destroy.c +null_destroy_OBJECTS = null_destroy.$(OBJEXT) +null_destroy_LDADD = $(LDADD) +null_destroy_DEPENDENCIES = $(top_builddir)/src/util/libmesautil.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +random_entry_SOURCES = random_entry.c +random_entry_OBJECTS = random_entry.$(OBJEXT) +random_entry_LDADD = $(LDADD) +random_entry_DEPENDENCIES = $(top_builddir)/src/util/libmesautil.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +remove_null_SOURCES = remove_null.c +remove_null_OBJECTS = remove_null.$(OBJEXT) +remove_null_LDADD = $(LDADD) +remove_null_DEPENDENCIES = $(top_builddir)/src/util/libmesautil.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +replacement_SOURCES = replacement.c +replacement_OBJECTS = replacement.$(OBJEXT) +replacement_LDADD = $(LDADD) +replacement_DEPENDENCIES = $(top_builddir)/src/util/libmesautil.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/bin/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = collision.c delete_and_lookup.c delete_management.c \ + destroy_callback.c insert_and_lookup.c insert_many.c \ + null_destroy.c random_entry.c remove_null.c replacement.c +DIST_SOURCES = collision.c delete_and_lookup.c delete_management.c \ + destroy_callback.c insert_and_lookup.c insert_many.c \ + null_destroy.c random_entry.c remove_null.c replacement.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/bin/depcomp \ + $(top_srcdir)/bin/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDGPU_CFLAGS = @AMDGPU_CFLAGS@ +AMDGPU_LIBS = @AMDGPU_LIBS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BSYMBOLIC = @BSYMBOLIC@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLANG_RESOURCE_DIR = @CLANG_RESOURCE_DIR@ +CLOCK_LIB = @CLOCK_LIB@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +D3D_DRIVER_INSTALL_DIR = @D3D_DRIVER_INSTALL_DIR@ +DEFINES = @DEFINES@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DLOPEN_LIBS = @DLOPEN_LIBS@ +DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ +DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ +DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ +DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ +DRIGL_CFLAGS = @DRIGL_CFLAGS@ +DRIGL_LIBS = @DRIGL_LIBS@ +DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@ +DRI_DRIVER_SEARCH_DIR = @DRI_DRIVER_SEARCH_DIR@ +DRI_LIB_DEPS = @DRI_LIB_DEPS@ +DRI_PC_REQ_PRIV = @DRI_PC_REQ_PRIV@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGL_CFLAGS = @EGL_CFLAGS@ +EGL_CLIENT_APIS = @EGL_CLIENT_APIS@ +EGL_LIB_DEPS = @EGL_LIB_DEPS@ +EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@ +EGREP = @EGREP@ +ELF_LIB = @ELF_LIB@ +EXEEXT = @EXEEXT@ +EXPAT_CFLAGS = @EXPAT_CFLAGS@ +EXPAT_LIBS = @EXPAT_LIBS@ +FGREP = @FGREP@ +FREEDRENO_CFLAGS = @FREEDRENO_CFLAGS@ +FREEDRENO_LIBS = @FREEDRENO_LIBS@ +GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@ +GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@ +GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@ +GC_SECTIONS = @GC_SECTIONS@ +GLESv1_CM_LIB_DEPS = @GLESv1_CM_LIB_DEPS@ +GLESv1_CM_PC_LIB_PRIV = @GLESv1_CM_PC_LIB_PRIV@ +GLESv2_LIB_DEPS = @GLESv2_LIB_DEPS@ +GLESv2_PC_LIB_PRIV = @GLESv2_PC_LIB_PRIV@ +GLPROTO_CFLAGS = @GLPROTO_CFLAGS@ +GLPROTO_LIBS = @GLPROTO_LIBS@ +GLX_TLS = @GLX_TLS@ +GL_LIB = @GL_LIB@ +GL_LIB_DEPS = @GL_LIB_DEPS@ +GL_PC_CFLAGS = @GL_PC_CFLAGS@ +GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@ +GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@ +GREP = @GREP@ +HAVE_XF86VIDMODE = @HAVE_XF86VIDMODE@ +INDENT = @INDENT@ +INDENT_FLAGS = @INDENT_FLAGS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTEL_CFLAGS = @INTEL_CFLAGS@ +INTEL_LIBS = @INTEL_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LD_NO_UNDEFINED = @LD_NO_UNDEFINED@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@ +LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@ +LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ +LIBDRM_LIBS = @LIBDRM_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUDEV_CFLAGS = @LIBUDEV_CFLAGS@ +LIBUDEV_LIBS = @LIBUDEV_LIBS@ +LIB_DIR = @LIB_DIR@ +LIB_EXT = @LIB_EXT@ +LIPO = @LIPO@ +LLVM_BINDIR = @LLVM_BINDIR@ +LLVM_CFLAGS = @LLVM_CFLAGS@ +LLVM_CONFIG = @LLVM_CONFIG@ +LLVM_CPPFLAGS = @LLVM_CPPFLAGS@ +LLVM_CXXFLAGS = @LLVM_CXXFLAGS@ +LLVM_INCLUDEDIR = @LLVM_INCLUDEDIR@ +LLVM_LDFLAGS = @LLVM_LDFLAGS@ +LLVM_LIBDIR = @LLVM_LIBDIR@ +LLVM_LIBS = @LLVM_LIBS@ +LLVM_VERSION = @LLVM_VERSION@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MESA_LLVM = @MESA_LLVM@ +MKDIR_P = @MKDIR_P@ +MSVC2008_COMPAT_CFLAGS = @MSVC2008_COMPAT_CFLAGS@ +MSVC2008_COMPAT_CXXFLAGS = @MSVC2008_COMPAT_CXXFLAGS@ +MSVC2013_COMPAT_CFLAGS = @MSVC2013_COMPAT_CFLAGS@ +MSVC2013_COMPAT_CXXFLAGS = @MSVC2013_COMPAT_CXXFLAGS@ +NINE_MAJOR = @NINE_MAJOR@ +NINE_MINOR = @NINE_MINOR@ +NINE_TINY = @NINE_TINY@ +NINE_VERSION = @NINE_VERSION@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NOUVEAU_CFLAGS = @NOUVEAU_CFLAGS@ +NOUVEAU_LIBS = @NOUVEAU_LIBS@ +NVVIEUX_CFLAGS = @NVVIEUX_CFLAGS@ +NVVIEUX_LIBS = @NVVIEUX_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OMX_CFLAGS = @OMX_CFLAGS@ +OMX_LIBS = @OMX_LIBS@ +OMX_LIB_INSTALL_DIR = @OMX_LIB_INSTALL_DIR@ +OPENCL_LIBNAME = @OPENCL_LIBNAME@ +OPENCL_VERSION = @OPENCL_VERSION@ +OSMESA_LIB = @OSMESA_LIB@ +OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@ +OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@ +OSMESA_PC_REQ = @OSMESA_PC_REQ@ +OSMESA_VERSION = @OSMESA_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +PRESENTPROTO_CFLAGS = @PRESENTPROTO_CFLAGS@ +PRESENTPROTO_LIBS = @PRESENTPROTO_LIBS@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +PYTHON2 = @PYTHON2@ +RADEON_CFLAGS = @RADEON_CFLAGS@ +RADEON_LIBS = @RADEON_LIBS@ +RANLIB = @RANLIB@ +RM = @RM@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SSE41_CFLAGS = @SSE41_CFLAGS@ +STRIP = @STRIP@ +VA_CFLAGS = @VA_CFLAGS@ +VA_LIBS = @VA_LIBS@ +VA_LIB_INSTALL_DIR = @VA_LIB_INSTALL_DIR@ +VA_MAJOR = @VA_MAJOR@ +VA_MINOR = @VA_MINOR@ +VDPAU_CFLAGS = @VDPAU_CFLAGS@ +VDPAU_LIBS = @VDPAU_LIBS@ +VDPAU_LIB_INSTALL_DIR = @VDPAU_LIB_INSTALL_DIR@ +VDPAU_MAJOR = @VDPAU_MAJOR@ +VDPAU_MINOR = @VDPAU_MINOR@ +VERSION = @VERSION@ +VG_LIB_DEPS = @VG_LIB_DEPS@ +VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ +VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@ +VL_CFLAGS = @VL_CFLAGS@ +VL_LIBS = @VL_LIBS@ +WAYLAND_CFLAGS = @WAYLAND_CFLAGS@ +WAYLAND_LIBS = @WAYLAND_LIBS@ +WAYLAND_SCANNER = @WAYLAND_SCANNER@ +WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ +WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ +X11_INCLUDES = @X11_INCLUDES@ +XA_MAJOR = @XA_MAJOR@ +XA_MINOR = @XA_MINOR@ +XA_TINY = @XA_TINY@ +XA_VERSION = @XA_VERSION@ +XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@ +XCB_DRI2_LIBS = @XCB_DRI2_LIBS@ +XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@ +XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@ +XLIBGL_CFLAGS = @XLIBGL_CFLAGS@ +XLIBGL_LIBS = @XLIBGL_LIBS@ +XVMC_CFLAGS = @XVMC_CFLAGS@ +XVMC_LIBS = @XVMC_LIBS@ +XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@ +XVMC_MAJOR = @XVMC_MAJOR@ +XVMC_MINOR = @XVMC_MINOR@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acv_mako_found = @acv_mako_found@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +ifGNUmake = @ifGNUmake@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/util \ + $(DEFINES) + +LDADD = \ + $(top_builddir)/src/util/libmesautil.la \ + $(PTHREAD_LIBS) \ + $(DLOPEN_LIBS) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/util/tests/hash_table/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/util/tests/hash_table/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +collision$(EXEEXT): $(collision_OBJECTS) $(collision_DEPENDENCIES) $(EXTRA_collision_DEPENDENCIES) + @rm -f collision$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(collision_OBJECTS) $(collision_LDADD) $(LIBS) + +delete_and_lookup$(EXEEXT): $(delete_and_lookup_OBJECTS) $(delete_and_lookup_DEPENDENCIES) $(EXTRA_delete_and_lookup_DEPENDENCIES) + @rm -f delete_and_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(delete_and_lookup_OBJECTS) $(delete_and_lookup_LDADD) $(LIBS) + +delete_management$(EXEEXT): $(delete_management_OBJECTS) $(delete_management_DEPENDENCIES) $(EXTRA_delete_management_DEPENDENCIES) + @rm -f delete_management$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(delete_management_OBJECTS) $(delete_management_LDADD) $(LIBS) + +destroy_callback$(EXEEXT): $(destroy_callback_OBJECTS) $(destroy_callback_DEPENDENCIES) $(EXTRA_destroy_callback_DEPENDENCIES) + @rm -f destroy_callback$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(destroy_callback_OBJECTS) $(destroy_callback_LDADD) $(LIBS) + +insert_and_lookup$(EXEEXT): $(insert_and_lookup_OBJECTS) $(insert_and_lookup_DEPENDENCIES) $(EXTRA_insert_and_lookup_DEPENDENCIES) + @rm -f insert_and_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(insert_and_lookup_OBJECTS) $(insert_and_lookup_LDADD) $(LIBS) + +insert_many$(EXEEXT): $(insert_many_OBJECTS) $(insert_many_DEPENDENCIES) $(EXTRA_insert_many_DEPENDENCIES) + @rm -f insert_many$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(insert_many_OBJECTS) $(insert_many_LDADD) $(LIBS) + +null_destroy$(EXEEXT): $(null_destroy_OBJECTS) $(null_destroy_DEPENDENCIES) $(EXTRA_null_destroy_DEPENDENCIES) + @rm -f null_destroy$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(null_destroy_OBJECTS) $(null_destroy_LDADD) $(LIBS) + +random_entry$(EXEEXT): $(random_entry_OBJECTS) $(random_entry_DEPENDENCIES) $(EXTRA_random_entry_DEPENDENCIES) + @rm -f random_entry$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(random_entry_OBJECTS) $(random_entry_LDADD) $(LIBS) + +remove_null$(EXEEXT): $(remove_null_OBJECTS) $(remove_null_DEPENDENCIES) $(EXTRA_remove_null_DEPENDENCIES) + @rm -f remove_null$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(remove_null_OBJECTS) $(remove_null_LDADD) $(LIBS) + +replacement$(EXEEXT): $(replacement_OBJECTS) $(replacement_DEPENDENCIES) $(EXTRA_replacement_DEPENDENCIES) + @rm -f replacement$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(replacement_OBJECTS) $(replacement_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delete_and_lookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delete_management.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/destroy_callback.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/insert_and_lookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/insert_many.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/null_destroy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random_entry.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remove_null.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/replacement.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +collision.log: collision$(EXEEXT) + @p='collision$(EXEEXT)'; \ + b='collision'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +delete_and_lookup.log: delete_and_lookup$(EXEEXT) + @p='delete_and_lookup$(EXEEXT)'; \ + b='delete_and_lookup'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +delete_management.log: delete_management$(EXEEXT) + @p='delete_management$(EXEEXT)'; \ + b='delete_management'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +destroy_callback.log: destroy_callback$(EXEEXT) + @p='destroy_callback$(EXEEXT)'; \ + b='destroy_callback'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +insert_and_lookup.log: insert_and_lookup$(EXEEXT) + @p='insert_and_lookup$(EXEEXT)'; \ + b='insert_and_lookup'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +insert_many.log: insert_many$(EXEEXT) + @p='insert_many$(EXEEXT)'; \ + b='insert_many'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +null_destroy.log: null_destroy$(EXEEXT) + @p='null_destroy$(EXEEXT)'; \ + b='null_destroy'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +random_entry.log: random_entry$(EXEEXT) + @p='random_entry$(EXEEXT)'; \ + b='random_entry'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +remove_null.log: remove_null$(EXEEXT) + @p='remove_null$(EXEEXT)'; \ + b='remove_null'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +replacement.log: replacement$(EXEEXT) + @p='replacement$(EXEEXT)'; \ + b='replacement'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/mesa/src/util/tests/hash_table/collision.c b/lib/mesa/src/util/tests/hash_table/collision.c new file mode 100644 index 000000000..69a4c29ec --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/collision.c @@ -0,0 +1,95 @@ +/* + * Copyright © 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + */ + +#include +#include +#include +#include +#include "hash_table.h" + +int +main(int argc, char **argv) +{ + struct hash_table *ht; + const char *str1 = "test1"; + const char *str2 = "test2"; + const char *str3 = "test3"; + struct hash_entry *entry1, *entry2, *search_entry; + uint32_t bad_hash = 5; + int i; + + (void) argc; + (void) argv; + + ht = _mesa_hash_table_create(NULL, NULL, _mesa_key_string_equal); + + /* Insert some items. Inserting 3 items forces a rehash and the new + * table size is big enough that we don't get rehashes later. + */ + _mesa_hash_table_insert_pre_hashed(ht, bad_hash, str1, NULL); + _mesa_hash_table_insert_pre_hashed(ht, bad_hash, str2, NULL); + _mesa_hash_table_insert_pre_hashed(ht, bad_hash, str3, NULL); + + entry1 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str1); + assert(entry1->key == str1); + + entry2 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str2); + assert(entry2->key == str2); + + /* Check that we can still find #1 after inserting #2 */ + entry1 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str1); + assert(entry1->key == str1); + + /* Remove the collided entry and look again. */ + _mesa_hash_table_remove(ht, entry1); + entry2 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str2); + assert(entry2->key == str2); + + /* Try inserting #2 again and make sure it gets overwritten */ + _mesa_hash_table_insert_pre_hashed(ht, bad_hash, str2, NULL); + entry2 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str2); + hash_table_foreach(ht, search_entry) { + assert(search_entry == entry2 || search_entry->key != str2); + } + + /* Put str1 back, then spam junk into the table to force a + * resize and make sure we can still find them both. + */ + _mesa_hash_table_insert_pre_hashed(ht, bad_hash, str1, NULL); + for (i = 0; i < 100; i++) { + char *key = malloc(10); + sprintf(key, "spam%d", i); + _mesa_hash_table_insert_pre_hashed(ht, _mesa_hash_string(key), key, NULL); + } + entry1 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str1); + assert(entry1->key == str1); + entry2 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str2); + assert(entry2->key == str2); + + _mesa_hash_table_destroy(ht, NULL); + + return 0; +} diff --git a/lib/mesa/src/util/tests/hash_table/delete_and_lookup.c b/lib/mesa/src/util/tests/hash_table/delete_and_lookup.c new file mode 100644 index 000000000..4f70509d0 --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/delete_and_lookup.c @@ -0,0 +1,76 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + */ + +#include +#include +#include +#include +#include "hash_table.h" + +/* Return collisions, so we can test the deletion behavior for chained + * objects. + */ +static uint32_t +badhash(const void *key) +{ + (void) key; + return 1; +} + +int +main(int argc, char **argv) +{ + struct hash_table *ht; + const char *str1 = "test1"; + const char *str2 = "test2"; + struct hash_entry *entry; + + (void) argc; + (void) argv; + + ht = _mesa_hash_table_create(NULL, badhash, _mesa_key_string_equal); + + _mesa_hash_table_insert(ht, str1, NULL); + _mesa_hash_table_insert(ht, str2, NULL); + + entry = _mesa_hash_table_search(ht, str2); + assert(strcmp(entry->key, str2) == 0); + + entry = _mesa_hash_table_search(ht, str1); + assert(strcmp(entry->key, str1) == 0); + + _mesa_hash_table_remove(ht, entry); + + entry = _mesa_hash_table_search(ht, str1); + assert(entry == NULL); + + entry = _mesa_hash_table_search(ht, str2); + assert(strcmp(entry->key, str2) == 0); + + _mesa_hash_table_destroy(ht, NULL); + + return 0; +} diff --git a/lib/mesa/src/util/tests/hash_table/delete_management.c b/lib/mesa/src/util/tests/hash_table/delete_management.c new file mode 100644 index 000000000..127d81b3c --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/delete_management.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + */ + +#include +#include +#include +#include +#include "hash_table.h" + +static uint32_t +key_value(const void *key) +{ + return *(const uint32_t *)key; +} + +static bool +uint32_t_key_equals(const void *a, const void *b) +{ + return key_value(a) == key_value(b); +} + +int +main(int argc, char **argv) +{ + struct hash_table *ht; + struct hash_entry *entry; + unsigned size = 10000; + uint32_t keys[size]; + uint32_t i; + + (void) argc; + (void) argv; + + ht = _mesa_hash_table_create(NULL, key_value, uint32_t_key_equals); + + for (i = 0; i < size; i++) { + keys[i] = i; + + _mesa_hash_table_insert(ht, keys + i, NULL); + + if (i >= 100) { + uint32_t delete_value = i - 100; + entry = _mesa_hash_table_search(ht, &delete_value); + _mesa_hash_table_remove(ht, entry); + } + } + + /* Make sure that all our entries were present at the end. */ + for (i = size - 100; i < size; i++) { + entry = _mesa_hash_table_search(ht, keys + i); + assert(entry); + assert(key_value(entry->key) == i); + } + + /* Make sure that no extra entries got in */ + for (entry = _mesa_hash_table_next_entry(ht, NULL); + entry != NULL; + entry = _mesa_hash_table_next_entry(ht, entry)) { + assert(key_value(entry->key) >= size - 100 && + key_value(entry->key) < size); + } + assert(ht->entries == 100); + + _mesa_hash_table_destroy(ht, NULL); + + return 0; +} diff --git a/lib/mesa/src/util/tests/hash_table/destroy_callback.c b/lib/mesa/src/util/tests/hash_table/destroy_callback.c new file mode 100644 index 000000000..1c18ca3e3 --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/destroy_callback.c @@ -0,0 +1,68 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + */ + +#include +#include +#include +#include +#include "hash_table.h" + +static const char *str1 = "test1"; +static const char *str2 = "test2"; +static int delete_str1 = 0; +static int delete_str2 = 0; + +static void +delete_callback(struct hash_entry *entry) +{ + if (strcmp(entry->key, str1) == 0) + delete_str1 = 1; + else if (strcmp(entry->key, str2) == 0) + delete_str2 = 1; + else + abort(); +} + +int +main(int argc, char **argv) +{ + struct hash_table *ht; + + (void) argc; + (void) argv; + + ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string, + _mesa_key_string_equal); + + _mesa_hash_table_insert(ht, str1, NULL); + _mesa_hash_table_insert(ht, str2, NULL); + + _mesa_hash_table_destroy(ht, delete_callback); + + assert(delete_str1 && delete_str2); + + return 0; +} diff --git a/lib/mesa/src/util/tests/hash_table/insert_and_lookup.c b/lib/mesa/src/util/tests/hash_table/insert_and_lookup.c new file mode 100644 index 000000000..98e719ff5 --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/insert_and_lookup.c @@ -0,0 +1,59 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + */ + +#include +#include +#include +#include +#include "hash_table.h" + +int +main(int argc, char **argv) +{ + struct hash_table *ht; + const char *str1 = "test1"; + const char *str2 = "test2"; + struct hash_entry *entry; + + (void) argc; + (void) argv; + + ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string, + _mesa_key_string_equal); + + _mesa_hash_table_insert(ht, str1, NULL); + _mesa_hash_table_insert(ht, str2, NULL); + + entry = _mesa_hash_table_search(ht, str1); + assert(strcmp(entry->key, str1) == 0); + + entry = _mesa_hash_table_search(ht, str2); + assert(strcmp(entry->key, str2) == 0); + + _mesa_hash_table_destroy(ht, NULL); + + return 0; +} diff --git a/lib/mesa/src/util/tests/hash_table/insert_many.c b/lib/mesa/src/util/tests/hash_table/insert_many.c new file mode 100644 index 000000000..b07e40842 --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/insert_many.c @@ -0,0 +1,75 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + */ + +#include +#include +#include +#include +#include "hash_table.h" + +static uint32_t +key_value(const void *key) +{ + return *(const uint32_t *)key; +} + +static bool +uint32_t_key_equals(const void *a, const void *b) +{ + return key_value(a) == key_value(b); +} + +int +main(int argc, char **argv) +{ + struct hash_table *ht; + struct hash_entry *entry; + unsigned size = 10000; + uint32_t keys[size]; + uint32_t i; + + (void) argc; + (void) argv; + + ht = _mesa_hash_table_create(NULL, key_value, uint32_t_key_equals); + + for (i = 0; i < size; i++) { + keys[i] = i; + + _mesa_hash_table_insert(ht, keys + i, NULL); + } + + for (i = 0; i < size; i++) { + entry = _mesa_hash_table_search(ht, keys + i); + assert(entry); + assert(key_value(entry->key) == i); + } + assert(ht->entries == size); + + _mesa_hash_table_destroy(ht, NULL); + + return 0; +} diff --git a/lib/mesa/src/util/tests/hash_table/null_destroy.c b/lib/mesa/src/util/tests/hash_table/null_destroy.c new file mode 100644 index 000000000..2b4caf5e2 --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/null_destroy.c @@ -0,0 +1,40 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + */ + +#include +#include +#include "hash_table.h" + +int +main(int argc, char **argv) +{ + (void) argc; + (void) argv; + + _mesa_hash_table_destroy(NULL, NULL); + + return 0; +} diff --git a/lib/mesa/src/util/tests/hash_table/random_entry.c b/lib/mesa/src/util/tests/hash_table/random_entry.c new file mode 100644 index 000000000..d1bc44aeb --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/random_entry.c @@ -0,0 +1,91 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + */ + +#include +#include +#include +#include +#include "hash_table.h" + +static uint32_t +key_value(const void *key) +{ + return *(const uint32_t *)key; +} + +static bool +uint32_t_key_equals(const void *a, const void *b) +{ + return key_value(a) == key_value(b); +} + +static bool +uint32_t_key_is_even(struct hash_entry *entry) +{ + return (key_value(entry->key) & 1) == 0; +} + +int +main(int argc, char **argv) +{ + struct hash_table *ht; + struct hash_entry *entry; + unsigned size = 10000; + uint32_t keys[size]; + uint32_t i, random_value; + + (void) argc; + (void) argv; + + ht = _mesa_hash_table_create(NULL, key_value, uint32_t_key_equals); + + for (i = 0; i < size; i++) { + keys[i] = i; + + _mesa_hash_table_insert(ht, keys + i, NULL); + } + + /* Test the no-predicate case. */ + entry = _mesa_hash_table_random_entry(ht, NULL); + assert(entry); + + /* Check that we're getting different entries and that the predicate + * works. + */ + for (i = 0; i < 100; i++) { + entry = _mesa_hash_table_random_entry(ht, uint32_t_key_is_even); + assert(entry); + assert((key_value(entry->key) & 1) == 0); + if (i == 0 || key_value(entry->key) != random_value) + break; + random_value = key_value(entry->key); + } + assert(i != 100); + + _mesa_hash_table_destroy(ht, NULL); + + return 0; +} diff --git a/lib/mesa/src/util/tests/hash_table/remove_null.c b/lib/mesa/src/util/tests/hash_table/remove_null.c new file mode 100644 index 000000000..7042f5e93 --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/remove_null.c @@ -0,0 +1,45 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + */ + +#include +#include +#include +#include +#include "hash_table.h" + +int +main(int argc, char **argv) +{ + struct hash_table *ht; + + ht = _mesa_hash_table_create(NULL, NULL, _mesa_key_string_equal); + + _mesa_hash_table_remove(ht, NULL); + + _mesa_hash_table_destroy(ht, NULL); + + return 0; +} diff --git a/lib/mesa/src/util/tests/hash_table/replacement.c b/lib/mesa/src/util/tests/hash_table/replacement.c new file mode 100644 index 000000000..58c22aeb8 --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/replacement.c @@ -0,0 +1,66 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + */ + +#include +#include +#include +#include +#include "hash_table.h" + +int +main(int argc, char **argv) +{ + struct hash_table *ht; + char *str1 = strdup("test1"); + char *str2 = strdup("test1"); + struct hash_entry *entry; + + (void) argc; + (void) argv; + + assert(str1 != str2); + + ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string, + _mesa_key_string_equal); + + _mesa_hash_table_insert(ht, str1, str1); + _mesa_hash_table_insert(ht, str2, str2); + + entry = _mesa_hash_table_search(ht, str1); + assert(entry); + assert(entry->data == str2); + + _mesa_hash_table_remove(ht, entry); + + entry = _mesa_hash_table_search(ht, str1); + assert(!entry); + + _mesa_hash_table_destroy(ht, NULL); + free(str1); + free(str2); + + return 0; +} diff --git a/lib/mesa/src/util/texcompress_rgtc_tmp.h b/lib/mesa/src/util/texcompress_rgtc_tmp.h new file mode 100644 index 000000000..6bbae5ead --- /dev/null +++ b/lib/mesa/src/util/texcompress_rgtc_tmp.h @@ -0,0 +1,418 @@ +/* + * Copyright (C) 2011 Red Hat Inc. + * + * block compression parts are: + * Copyright (C) 2004 Roland Scheidegger All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: + * Dave Airlie + */ + +/* included by texcompress_rgtc to define byte/ubyte compressors */ + +void TAG(fetch_texel_rgtc)(unsigned srcRowStride, const TYPE *pixdata, + unsigned i, unsigned j, TYPE *value, unsigned comps) +{ + TYPE decode; + const TYPE *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8 * comps); + const TYPE alpha0 = blksrc[0]; + const TYPE alpha1 = blksrc[1]; + const char bit_pos = ((j&3) * 4 + (i&3)) * 3; + const unsigned char acodelow = blksrc[2 + bit_pos / 8]; + const unsigned char acodehigh = (3 + bit_pos / 8) < 8 ? blksrc[3 + bit_pos / 8] : 0; + const unsigned char code = (acodelow >> (bit_pos & 0x7) | + (acodehigh << (8 - (bit_pos & 0x7)))) & 0x7; + + if (code == 0) + decode = alpha0; + else if (code == 1) + decode = alpha1; + else if (alpha0 > alpha1) + decode = ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7); + else if (code < 6) + decode = ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5); + else if (code == 6) + decode = T_MIN; + else + decode = T_MAX; + + *value = decode; +} + +static void TAG(write_rgtc_encoded_channel)(TYPE *blkaddr, + TYPE alphabase1, + TYPE alphabase2, + TYPE alphaenc[16]) +{ + *blkaddr++ = alphabase1; + *blkaddr++ = alphabase2; + *blkaddr++ = alphaenc[0] | (alphaenc[1] << 3) | ((alphaenc[2] & 3) << 6); + *blkaddr++ = (alphaenc[2] >> 2) | (alphaenc[3] << 1) | (alphaenc[4] << 4) | ((alphaenc[5] & 1) << 7); + *blkaddr++ = (alphaenc[5] >> 1) | (alphaenc[6] << 2) | (alphaenc[7] << 5); + *blkaddr++ = alphaenc[8] | (alphaenc[9] << 3) | ((alphaenc[10] & 3) << 6); + *blkaddr++ = (alphaenc[10] >> 2) | (alphaenc[11] << 1) | (alphaenc[12] << 4) | ((alphaenc[13] & 1) << 7); + *blkaddr++ = (alphaenc[13] >> 1) | (alphaenc[14] << 2) | (alphaenc[15] << 5); +} + +void TAG(encode_rgtc_ubyte)(TYPE *blkaddr, TYPE srccolors[4][4], + int numxpixels, int numypixels) +{ + TYPE alphabase[2], alphause[2]; + short alphatest[2] = { 0 }; + unsigned int alphablockerror1, alphablockerror2, alphablockerror3; + TYPE i, j, aindex, acutValues[7]; + TYPE alphaenc1[16], alphaenc2[16], alphaenc3[16]; + int alphaabsmin = 0, alphaabsmax = 0; + short alphadist; + + /* find lowest and highest alpha value in block, alphabase[0] lowest, alphabase[1] highest */ + alphabase[0] = T_MAX; alphabase[1] = T_MIN; + for (j = 0; j < numypixels; j++) { + for (i = 0; i < numxpixels; i++) { + if (srccolors[j][i] == T_MIN) + alphaabsmin = 1; + else if (srccolors[j][i] == T_MAX) + alphaabsmax = 1; + else { + if (srccolors[j][i] > alphabase[1]) + alphabase[1] = srccolors[j][i]; + if (srccolors[j][i] < alphabase[0]) + alphabase[0] = srccolors[j][i]; + } + } + } + + + if (((alphabase[0] > alphabase[1]) && !(alphaabsmin && alphaabsmax)) + || (alphabase[0] == alphabase[1] && !alphaabsmin && !alphaabsmax)) { /* one color, either max or min */ + /* shortcut here since it is a very common case (and also avoids later problems) */ + /* could also thest for alpha0 == alpha1 (and not min/max), but probably not common, so don't bother */ + + *blkaddr++ = srccolors[0][0]; + blkaddr++; + *blkaddr++ = 0; + *blkaddr++ = 0; + *blkaddr++ = 0; + *blkaddr++ = 0; + *blkaddr++ = 0; + *blkaddr++ = 0; +#if RGTC_DEBUG + fprintf(stderr, "enc0 used\n"); +#endif + return; + } + + /* find best encoding for alpha0 > alpha1 */ + /* it's possible this encoding is better even if both alphaabsmin and alphaabsmax are true */ + alphablockerror1 = 0x0; + alphablockerror2 = 0xffffffff; + alphablockerror3 = 0xffffffff; + if (alphaabsmin) alphause[0] = T_MIN; + else alphause[0] = alphabase[0]; + if (alphaabsmax) alphause[1] = T_MAX; + else alphause[1] = alphabase[1]; + /* calculate the 7 cut values, just the middle between 2 of the computed alpha values */ + for (aindex = 0; aindex < 7; aindex++) { + /* don't forget here is always rounded down */ + acutValues[aindex] = (alphause[0] * (2*aindex + 1) + alphause[1] * (14 - (2*aindex + 1))) / 14; + } + + for (j = 0; j < numypixels; j++) { + for (i = 0; i < numxpixels; i++) { + /* maybe it's overkill to have the most complicated calculation just for the error + calculation which we only need to figure out if encoding1 or encoding2 is better... */ + if (srccolors[j][i] > acutValues[0]) { + alphaenc1[4*j + i] = 0; + alphadist = srccolors[j][i] - alphause[1]; + } + else if (srccolors[j][i] > acutValues[1]) { + alphaenc1[4*j + i] = 2; + alphadist = srccolors[j][i] - (alphause[1] * 6 + alphause[0] * 1) / 7; + } + else if (srccolors[j][i] > acutValues[2]) { + alphaenc1[4*j + i] = 3; + alphadist = srccolors[j][i] - (alphause[1] * 5 + alphause[0] * 2) / 7; + } + else if (srccolors[j][i] > acutValues[3]) { + alphaenc1[4*j + i] = 4; + alphadist = srccolors[j][i] - (alphause[1] * 4 + alphause[0] * 3) / 7; + } + else if (srccolors[j][i] > acutValues[4]) { + alphaenc1[4*j + i] = 5; + alphadist = srccolors[j][i] - (alphause[1] * 3 + alphause[0] * 4) / 7; + } + else if (srccolors[j][i] > acutValues[5]) { + alphaenc1[4*j + i] = 6; + alphadist = srccolors[j][i] - (alphause[1] * 2 + alphause[0] * 5) / 7; + } + else if (srccolors[j][i] > acutValues[6]) { + alphaenc1[4*j + i] = 7; + alphadist = srccolors[j][i] - (alphause[1] * 1 + alphause[0] * 6) / 7; + } + else { + alphaenc1[4*j + i] = 1; + alphadist = srccolors[j][i] - alphause[0]; + } + alphablockerror1 += alphadist * alphadist; + } + } + +#if RGTC_DEBUG + for (i = 0; i < 16; i++) { + fprintf(stderr, "%d ", alphaenc1[i]); + } + fprintf(stderr, "cutVals "); + for (i = 0; i < 7; i++) { + fprintf(stderr, "%d ", acutValues[i]); + } + fprintf(stderr, "srcVals "); + for (j = 0; j < numypixels; j++) { + for (i = 0; i < numxpixels; i++) { + fprintf(stderr, "%d ", srccolors[j][i]); + } + } + fprintf(stderr, "\n"); +#endif + + /* it's not very likely this encoding is better if both alphaabsmin and alphaabsmax + are false but try it anyway */ + if (alphablockerror1 >= 32) { + + /* don't bother if encoding is already very good, this condition should also imply + we have valid alphabase colors which we absolutely need (alphabase[0] <= alphabase[1]) */ + alphablockerror2 = 0; + for (aindex = 0; aindex < 5; aindex++) { + /* don't forget here is always rounded down */ + acutValues[aindex] = (alphabase[0] * (10 - (2*aindex + 1)) + alphabase[1] * (2*aindex + 1)) / 10; + } + for (j = 0; j < numypixels; j++) { + for (i = 0; i < numxpixels; i++) { + /* maybe it's overkill to have the most complicated calculation just for the error + calculation which we only need to figure out if encoding1 or encoding2 is better... */ + if (srccolors[j][i] == T_MIN) { + alphaenc2[4*j + i] = 6; + alphadist = 0; + } + else if (srccolors[j][i] == T_MAX) { + alphaenc2[4*j + i] = 7; + alphadist = 0; + } + else if (srccolors[j][i] <= acutValues[0]) { + alphaenc2[4*j + i] = 0; + alphadist = srccolors[j][i] - alphabase[0]; + } + else if (srccolors[j][i] <= acutValues[1]) { + alphaenc2[4*j + i] = 2; + alphadist = srccolors[j][i] - (alphabase[0] * 4 + alphabase[1] * 1) / 5; + } + else if (srccolors[j][i] <= acutValues[2]) { + alphaenc2[4*j + i] = 3; + alphadist = srccolors[j][i] - (alphabase[0] * 3 + alphabase[1] * 2) / 5; + } + else if (srccolors[j][i] <= acutValues[3]) { + alphaenc2[4*j + i] = 4; + alphadist = srccolors[j][i] - (alphabase[0] * 2 + alphabase[1] * 3) / 5; + } + else if (srccolors[j][i] <= acutValues[4]) { + alphaenc2[4*j + i] = 5; + alphadist = srccolors[j][i] - (alphabase[0] * 1 + alphabase[1] * 4) / 5; + } + else { + alphaenc2[4*j + i] = 1; + alphadist = srccolors[j][i] - alphabase[1]; + } + alphablockerror2 += alphadist * alphadist; + } + } + + + /* skip this if the error is already very small + this encoding is MUCH better on average than #2 though, but expensive! */ + if ((alphablockerror2 > 96) && (alphablockerror1 > 96)) { + short blockerrlin1 = 0; + short blockerrlin2 = 0; + TYPE nralphainrangelow = 0; + TYPE nralphainrangehigh = 0; + alphatest[0] = T_MAX; + alphatest[1] = T_MIN; + /* if we have large range it's likely there are values close to 0/255, try to map them to 0/255 */ + for (j = 0; j < numypixels; j++) { + for (i = 0; i < numxpixels; i++) { + if ((srccolors[j][i] > alphatest[1]) && (srccolors[j][i] < (T_MAX -(alphabase[1] - alphabase[0]) / 28))) + alphatest[1] = srccolors[j][i]; + if ((srccolors[j][i] < alphatest[0]) && (srccolors[j][i] > (alphabase[1] - alphabase[0]) / 28)) + alphatest[0] = srccolors[j][i]; + } + } + /* shouldn't happen too often, don't really care about those degenerated cases */ + if (alphatest[1] <= alphatest[0]) { + alphatest[0] = T_MIN+1; + alphatest[1] = T_MAX-1; + } + for (aindex = 0; aindex < 5; aindex++) { + /* don't forget here is always rounded down */ + acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10; + } + + /* find the "average" difference between the alpha values and the next encoded value. + This is then used to calculate new base values. + Should there be some weighting, i.e. those values closer to alphatest[x] have more weight, + since they will see more improvement, and also because the values in the middle are somewhat + likely to get no improvement at all (because the base values might move in different directions)? + OTOH it would mean the values in the middle are even less likely to get an improvement + */ + for (j = 0; j < numypixels; j++) { + for (i = 0; i < numxpixels; i++) { + if (srccolors[j][i] <= alphatest[0] / 2) { + } + else if (srccolors[j][i] > ((T_MAX + alphatest[1]) / 2)) { + } + else if (srccolors[j][i] <= acutValues[0]) { + blockerrlin1 += (srccolors[j][i] - alphatest[0]); + nralphainrangelow += 1; + } + else if (srccolors[j][i] <= acutValues[1]) { + blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5); + blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5); + nralphainrangelow += 1; + nralphainrangehigh += 1; + } + else if (srccolors[j][i] <= acutValues[2]) { + blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5); + blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5); + nralphainrangelow += 1; + nralphainrangehigh += 1; + } + else if (srccolors[j][i] <= acutValues[3]) { + blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5); + blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5); + nralphainrangelow += 1; + nralphainrangehigh += 1; + } + else if (srccolors[j][i] <= acutValues[4]) { + blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5); + blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5); + nralphainrangelow += 1; + nralphainrangehigh += 1; + } + else { + blockerrlin2 += (srccolors[j][i] - alphatest[1]); + nralphainrangehigh += 1; + } + } + } + /* shouldn't happen often, needed to avoid div by zero */ + if (nralphainrangelow == 0) nralphainrangelow = 1; + if (nralphainrangehigh == 0) nralphainrangehigh = 1; + alphatest[0] = alphatest[0] + (blockerrlin1 / nralphainrangelow); +#if RGTC_DEBUG + fprintf(stderr, "block err lin low %d, nr %d\n", blockerrlin1, nralphainrangelow); + fprintf(stderr, "block err lin high %d, nr %d\n", blockerrlin2, nralphainrangehigh); +#endif + /* again shouldn't really happen often... */ + if (alphatest[0] < T_MIN) { + alphatest[0] = T_MIN; + } + alphatest[1] = alphatest[1] + (blockerrlin2 / nralphainrangehigh); + if (alphatest[1] > T_MAX) { + alphatest[1] = T_MAX; + } + + alphablockerror3 = 0; + for (aindex = 0; aindex < 5; aindex++) { + /* don't forget here is always rounded down */ + acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10; + } + for (j = 0; j < numypixels; j++) { + for (i = 0; i < numxpixels; i++) { + /* maybe it's overkill to have the most complicated calculation just for the error + calculation which we only need to figure out if encoding1 or encoding2 is better... */ + if (srccolors[j][i] <= alphatest[0] / 2) { + alphaenc3[4*j + i] = 6; + alphadist = srccolors[j][i]; + } + else if (srccolors[j][i] > ((T_MAX + alphatest[1]) / 2)) { + alphaenc3[4*j + i] = 7; + alphadist = T_MAX - srccolors[j][i]; + } + else if (srccolors[j][i] <= acutValues[0]) { + alphaenc3[4*j + i] = 0; + alphadist = srccolors[j][i] - alphatest[0]; + } + else if (srccolors[j][i] <= acutValues[1]) { + alphaenc3[4*j + i] = 2; + alphadist = srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5; + } + else if (srccolors[j][i] <= acutValues[2]) { + alphaenc3[4*j + i] = 3; + alphadist = srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5; + } + else if (srccolors[j][i] <= acutValues[3]) { + alphaenc3[4*j + i] = 4; + alphadist = srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5; + } + else if (srccolors[j][i] <= acutValues[4]) { + alphaenc3[4*j + i] = 5; + alphadist = srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5; + } + else { + alphaenc3[4*j + i] = 1; + alphadist = srccolors[j][i] - alphatest[1]; + } + alphablockerror3 += alphadist * alphadist; + } + } + } + } + + /* write the alpha values and encoding back. */ + if ((alphablockerror1 <= alphablockerror2) && (alphablockerror1 <= alphablockerror3)) { +#if RGTC_DEBUG + if (alphablockerror1 > 96) fprintf(stderr, "enc1 used, error %d\n", alphablockerror1); + fprintf(stderr,"w1: min %d max %d au0 %d au1 %d\n", + T_MIN, T_MAX, + alphause[1], alphause[0]); +#endif + + TAG(write_rgtc_encoded_channel)( blkaddr, alphause[1], alphause[0], alphaenc1 ); + } + else if (alphablockerror2 <= alphablockerror3) { +#if RGTC_DEBUG + if (alphablockerror2 > 96) fprintf(stderr, "enc2 used, error %d\n", alphablockerror2); + fprintf(stderr,"w2: min %d max %d au0 %d au1 %d\n", + T_MIN, T_MAX, + alphabase[0], alphabase[1]); +#endif + + TAG(write_rgtc_encoded_channel)( blkaddr, alphabase[0], alphabase[1], alphaenc2 ); + } + else { +#if RGTC_DEBUG + fprintf(stderr, "enc3 used, error %d\n", alphablockerror3); + fprintf(stderr,"w3: min %d max %d au0 %d au1 %d\n", + T_MIN, T_MAX, + alphatest[0], alphatest[1]); +#endif + + TAG(write_rgtc_encoded_channel)( blkaddr, (TYPE)alphatest[0], (TYPE)alphatest[1], alphaenc3 ); + } +} diff --git a/lib/mesa/src/util/u_atomic.h b/lib/mesa/src/util/u_atomic.h new file mode 100644 index 000000000..e38395ac6 --- /dev/null +++ b/lib/mesa/src/util/u_atomic.h @@ -0,0 +1,263 @@ +/** + * Many similar implementations exist. See for example libwsbm + * or the linux kernel include/atomic.h + * + * No copyright claimed on this file. + * + */ + +#include "no_extern_c.h" + +#ifndef U_ATOMIC_H +#define U_ATOMIC_H + +#include + +/* Favor OS-provided implementations. + * + * Where no OS-provided implementation is available, fall back to + * locally coded assembly, compiler intrinsic or ultimately a + * mutex-based implementation. + */ +#if defined(__sun) +#define PIPE_ATOMIC_OS_SOLARIS +#elif defined(_MSC_VER) +#define PIPE_ATOMIC_MSVC_INTRINSIC +#elif defined(__GNUC__) +#define PIPE_ATOMIC_GCC_INTRINSIC +#else +#error "Unsupported platform" +#endif + + +/* Implementation using GCC-provided synchronization intrinsics + */ +#if defined(PIPE_ATOMIC_GCC_INTRINSIC) + +#define PIPE_ATOMIC "GCC Sync Intrinsics" + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) +#define p_atomic_dec_zero(v) (__sync_sub_and_fetch((v), 1) == 0) +#define p_atomic_inc(v) (void) __sync_add_and_fetch((v), 1) +#define p_atomic_dec(v) (void) __sync_sub_and_fetch((v), 1) +#define p_atomic_add(v, i) (void) __sync_add_and_fetch((v), (i)) +#define p_atomic_inc_return(v) __sync_add_and_fetch((v), 1) +#define p_atomic_dec_return(v) __sync_sub_and_fetch((v), 1) +#define p_atomic_cmpxchg(v, old, _new) \ + __sync_val_compare_and_swap((v), (old), (_new)) + +#endif + + + +/* Unlocked version for single threaded environments, such as some + * windows kernel modules. + */ +#if defined(PIPE_ATOMIC_OS_UNLOCKED) + +#define PIPE_ATOMIC "Unlocked" + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) +#define p_atomic_dec_zero(_v) (p_atomic_dec_return(_v) == 0) +#define p_atomic_inc(_v) ((void) p_atomic_inc_return(_v)) +#define p_atomic_dec(_v) ((void) p_atomic_dec_return(_v)) +#define p_atomic_add(_v, _i) (*(_v) = *(_v) + (_i)) +#define p_atomic_inc_return(_v) (++(*(_v))) +#define p_atomic_dec_return(_v) (--(*(_v))) +#define p_atomic_cmpxchg(_v, _old, _new) (*(_v) == (_old) ? (*(_v) = (_new), (_old)) : *(_v)) + +#endif + + +#if defined(PIPE_ATOMIC_MSVC_INTRINSIC) + +#define PIPE_ATOMIC "MSVC Intrinsics" + +/* We use the Windows header's Interlocked*64 functions instead of the + * _Interlocked*64 intrinsics wherever we can, as support for the latter varies + * with target CPU, whereas Windows headers take care of all portability + * issues: using intrinsics where available, falling back to library + * implementations where not. + */ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#include +#include + +#if _MSC_VER < 1600 + +/* Implement _InterlockedCompareExchange8 in terms of _InterlockedCompareExchange16 */ +static __inline char +_InterlockedCompareExchange8(char volatile *destination8, char exchange8, char comparand8) +{ + INT_PTR destinationAddr = (INT_PTR)destination8; + short volatile *destination16 = (short volatile *)(destinationAddr & ~1); + const short shift8 = (destinationAddr & 1) * 8; + const short mask8 = 0xff << shift8; + short initial16 = *destination16; + char initial8 = initial16 >> shift8; + while (initial8 == comparand8) { + /* initial *destination8 matches, so try exchange it while keeping the + * neighboring byte untouched */ + short exchange16 = (initial16 & ~mask8) | ((short)exchange8 << shift8); + short comparand16 = initial16; + short initial16 = _InterlockedCompareExchange16(destination16, exchange16, comparand16); + if (initial16 == comparand16) { + /* succeeded */ + return comparand8; + } + /* something changed, retry with the new initial value */ + initial8 = initial16 >> shift8; + } + return initial8; +} + +/* Implement _InterlockedExchangeAdd16 in terms of _InterlockedCompareExchange16 */ +static __inline short +_InterlockedExchangeAdd16(short volatile *addend, short value) +{ + short initial = *addend; + short comparand; + do { + short exchange = initial + value; + comparand = initial; + /* if *addend==comparand then *addend=exchange, return original *addend */ + initial = _InterlockedCompareExchange16(addend, exchange, comparand); + } while(initial != comparand); + return comparand; +} + +/* Implement _InterlockedExchangeAdd8 in terms of _InterlockedCompareExchange8 */ +static __inline char +_InterlockedExchangeAdd8(char volatile *addend, char value) +{ + char initial = *addend; + char comparand; + do { + char exchange = initial + value; + comparand = initial; + initial = _InterlockedCompareExchange8(addend, exchange, comparand); + } while(initial != comparand); + return comparand; +} + +#endif /* _MSC_VER < 1600 */ + +/* MSVC supports decltype keyword, but it's only supported on C++ and doesn't + * quite work here; and if a C++-only solution is worthwhile, then it would be + * better to use templates / function overloading, instead of decltype magic. + * Therefore, we rely on implicit casting to LONGLONG for the functions that return + */ + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +#define p_atomic_dec_zero(_v) \ + (p_atomic_dec_return(_v) == 0) + +#define p_atomic_inc(_v) \ + ((void) p_atomic_inc_return(_v)) + +#define p_atomic_inc_return(_v) (\ + sizeof *(_v) == sizeof(short) ? _InterlockedIncrement16((short *) (_v)) : \ + sizeof *(_v) == sizeof(long) ? _InterlockedIncrement ((long *) (_v)) : \ + sizeof *(_v) == sizeof(__int64) ? InterlockedIncrement64 ((__int64 *)(_v)) : \ + (assert(!"should not get here"), 0)) + +#define p_atomic_dec(_v) \ + ((void) p_atomic_dec_return(_v)) + +#define p_atomic_dec_return(_v) (\ + sizeof *(_v) == sizeof(short) ? _InterlockedDecrement16((short *) (_v)) : \ + sizeof *(_v) == sizeof(long) ? _InterlockedDecrement ((long *) (_v)) : \ + sizeof *(_v) == sizeof(__int64) ? InterlockedDecrement64 ((__int64 *)(_v)) : \ + (assert(!"should not get here"), 0)) + +#define p_atomic_add(_v, _i) (\ + sizeof *(_v) == sizeof(char) ? _InterlockedExchangeAdd8 ((char *) (_v), (_i)) : \ + sizeof *(_v) == sizeof(short) ? _InterlockedExchangeAdd16((short *) (_v), (_i)) : \ + sizeof *(_v) == sizeof(long) ? _InterlockedExchangeAdd ((long *) (_v), (_i)) : \ + sizeof *(_v) == sizeof(__int64) ? InterlockedExchangeAdd64((__int64 *)(_v), (_i)) : \ + (assert(!"should not get here"), 0)) + +#define p_atomic_cmpxchg(_v, _old, _new) (\ + sizeof *(_v) == sizeof(char) ? _InterlockedCompareExchange8 ((char *) (_v), (char) (_new), (char) (_old)) : \ + sizeof *(_v) == sizeof(short) ? _InterlockedCompareExchange16((short *) (_v), (short) (_new), (short) (_old)) : \ + sizeof *(_v) == sizeof(long) ? _InterlockedCompareExchange ((long *) (_v), (long) (_new), (long) (_old)) : \ + sizeof *(_v) == sizeof(__int64) ? InterlockedCompareExchange64 ((__int64 *)(_v), (__int64)(_new), (__int64)(_old)) : \ + (assert(!"should not get here"), 0)) + +#endif + +#if defined(PIPE_ATOMIC_OS_SOLARIS) + +#define PIPE_ATOMIC "Solaris OS atomic functions" + +#include +#include + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +#define p_atomic_dec_zero(v) (\ + sizeof(*v) == sizeof(uint8_t) ? atomic_dec_8_nv ((uint8_t *)(v)) == 0 : \ + sizeof(*v) == sizeof(uint16_t) ? atomic_dec_16_nv((uint16_t *)(v)) == 0 : \ + sizeof(*v) == sizeof(uint32_t) ? atomic_dec_32_nv((uint32_t *)(v)) == 0 : \ + sizeof(*v) == sizeof(uint64_t) ? atomic_dec_64_nv((uint64_t *)(v)) == 0 : \ + (assert(!"should not get here"), 0)) + +#define p_atomic_inc(v) (void) (\ + sizeof(*v) == sizeof(uint8_t) ? atomic_inc_8 ((uint8_t *)(v)) : \ + sizeof(*v) == sizeof(uint16_t) ? atomic_inc_16((uint16_t *)(v)) : \ + sizeof(*v) == sizeof(uint32_t) ? atomic_inc_32((uint32_t *)(v)) : \ + sizeof(*v) == sizeof(uint64_t) ? atomic_inc_64((uint64_t *)(v)) : \ + (assert(!"should not get here"), 0)) + +#define p_atomic_inc_return(v) ((__typeof(*v)) \ + sizeof(*v) == sizeof(uint8_t) ? atomic_inc_8_nv ((uint8_t *)(v)) : \ + sizeof(*v) == sizeof(uint16_t) ? atomic_inc_16_nv((uint16_t *)(v)) : \ + sizeof(*v) == sizeof(uint32_t) ? atomic_inc_32_nv((uint32_t *)(v)) : \ + sizeof(*v) == sizeof(uint64_t) ? atomic_inc_64_nv((uint64_t *)(v)) : \ + (assert(!"should not get here"), 0)) + +#define p_atomic_dec(v) ((void) \ + sizeof(*v) == sizeof(uint8_t) ? atomic_dec_8 ((uint8_t *)(v)) : \ + sizeof(*v) == sizeof(uint16_t) ? atomic_dec_16((uint16_t *)(v)) : \ + sizeof(*v) == sizeof(uint32_t) ? atomic_dec_32((uint32_t *)(v)) : \ + sizeof(*v) == sizeof(uint64_t) ? atomic_dec_64((uint64_t *)(v)) : \ + (assert(!"should not get here"), 0)) + +#define p_atomic_dec_return(v) ((__typeof(*v)) \ + sizeof(*v) == sizeof(uint8_t) ? atomic_dec_8_nv ((uint8_t *)(v)) : \ + sizeof(*v) == sizeof(uint16_t) ? atomic_dec_16_nv((uint16_t *)(v)) : \ + sizeof(*v) == sizeof(uint32_t) ? atomic_dec_32_nv((uint32_t *)(v)) : \ + sizeof(*v) == sizeof(uint64_t) ? atomic_dec_64_nv((uint64_t *)(v)) : \ + (assert(!"should not get here"), 0)) + +#define p_atomic_add(v, i) ((void) \ + sizeof(*v) == sizeof(uint8_t) ? atomic_add_8 ((uint8_t *)(v), (i)) : \ + sizeof(*v) == sizeof(uint16_t) ? atomic_add_16((uint16_t *)(v), (i)) : \ + sizeof(*v) == sizeof(uint32_t) ? atomic_add_32((uint32_t *)(v), (i)) : \ + sizeof(*v) == sizeof(uint64_t) ? atomic_add_64((uint64_t *)(v), (i)) : \ + (assert(!"should not get here"), 0)) + +#define p_atomic_cmpxchg(v, old, _new) ((__typeof(*v)) \ + sizeof(*v) == sizeof(uint8_t) ? atomic_cas_8 ((uint8_t *)(v), (uint8_t )(old), (uint8_t )(_new)) : \ + sizeof(*v) == sizeof(uint16_t) ? atomic_cas_16((uint16_t *)(v), (uint16_t)(old), (uint16_t)(_new)) : \ + sizeof(*v) == sizeof(uint32_t) ? atomic_cas_32((uint32_t *)(v), (uint32_t)(old), (uint32_t)(_new)) : \ + sizeof(*v) == sizeof(uint64_t) ? atomic_cas_64((uint64_t *)(v), (uint64_t)(old), (uint64_t)(_new)) : \ + (assert(!"should not get here"), 0)) + +#endif + +#ifndef PIPE_ATOMIC +#error "No pipe_atomic implementation selected" +#endif + + + +#endif /* U_ATOMIC_H */ diff --git a/lib/mesa/src/util/u_atomic_test.c b/lib/mesa/src/util/u_atomic_test.c new file mode 100644 index 000000000..7844f6162 --- /dev/null +++ b/lib/mesa/src/util/u_atomic_test.c @@ -0,0 +1,162 @@ +/************************************************************************** + * + * Copyright 2014 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/* Force assertions, even on debug builds. */ +#undef NDEBUG + + +#include +#include +#include + +#include "u_atomic.h" + +#ifdef _MSC_VER +#pragma warning( disable : 28112 ) /* Accessing a local variable via an Interlocked function */ +#pragma warning( disable : 28113 ) /* A variable which is accessed via an Interlocked function must always be accessed via an Interlocked function */ +#endif + + +/* Test only assignment-like operations, which are supported on all types */ +#define test_atomic_assign(type, ones) \ + static void test_atomic_assign_##type (void) { \ + type v, r; \ + \ + p_atomic_set(&v, ones); \ + assert(v == ones && "p_atomic_set"); \ + \ + r = p_atomic_read(&v); \ + assert(r == ones && "p_atomic_read"); \ + \ + v = ones; \ + r = p_atomic_cmpxchg(&v, 0, 1); \ + assert(v == ones && "p_atomic_cmpxchg"); \ + assert(r == ones && "p_atomic_cmpxchg"); \ + r = p_atomic_cmpxchg(&v, ones, 0); \ + assert(v == 0 && "p_atomic_cmpxchg"); \ + assert(r == ones && "p_atomic_cmpxchg"); \ + \ + (void) r; \ + } + + +/* Test arithmetic operations that are supported on 8 bits integer types */ +#define test_atomic_8bits(type, ones) \ + test_atomic_assign(type, ones) \ + \ + static void test_atomic_8bits_##type (void) { \ + type v, r; \ + \ + test_atomic_assign_##type(); \ + \ + v = 23; \ + p_atomic_add(&v, 42); \ + r = p_atomic_read(&v); \ + assert(r == 65 && "p_atomic_add"); \ + \ + (void) r; \ + } + + +/* Test all operations */ +#define test_atomic(type, ones) \ + test_atomic_8bits(type, ones) \ + \ + static void test_atomic_##type (void) { \ + type v, r; \ + bool b; \ + \ + test_atomic_8bits_##type(); \ + \ + v = 2; \ + b = p_atomic_dec_zero(&v); \ + assert(v == 1 && "p_atomic_dec_zero"); \ + assert(b == false && "p_atomic_dec_zero"); \ + b = p_atomic_dec_zero(&v); \ + assert(v == 0 && "p_atomic_dec_zero"); \ + assert(b == true && "p_atomic_dec_zero"); \ + b = p_atomic_dec_zero(&v); \ + assert(v == ones && "p_atomic_dec_zero"); \ + assert(b == false && "p_atomic_dec_zero"); \ + \ + v = ones; \ + p_atomic_inc(&v); \ + assert(v == 0 && "p_atomic_inc"); \ + \ + v = ones; \ + r = p_atomic_inc_return(&v); \ + assert(v == 0 && "p_atomic_inc_return"); \ + assert(r == v && "p_atomic_inc_return"); \ + \ + v = 0; \ + p_atomic_dec(&v); \ + assert(v == ones && "p_atomic_dec"); \ + \ + v = 0; \ + r = p_atomic_dec_return(&v); \ + assert(v == ones && "p_atomic_dec_return"); \ + assert(r == v && "p_atomic_dec_return"); \ + \ + (void) r; \ + (void) b; \ + } + + +test_atomic(int, -1) +test_atomic(unsigned, ~0U) + +test_atomic(int16_t, INT16_C(-1)) +test_atomic(uint16_t, UINT16_C(0xffff)) +test_atomic(int32_t, INT32_C(-1)) +test_atomic(uint32_t, UINT32_C(0xffffffff)) +test_atomic(int64_t, INT64_C(-1)) +test_atomic(uint64_t, UINT64_C(0xffffffffffffffff)) + +test_atomic_8bits(int8_t, INT8_C(-1)) +test_atomic_8bits(uint8_t, UINT8_C(0xff)) +test_atomic_assign(bool, true) + +int +main() +{ + test_atomic_int(); + test_atomic_unsigned(); + + test_atomic_int16_t(); + test_atomic_uint16_t(); + test_atomic_int32_t(); + test_atomic_uint32_t(); + test_atomic_int64_t(); + test_atomic_uint64_t(); + + test_atomic_8bits_int8_t(); + test_atomic_8bits_uint8_t(); + test_atomic_assign_bool(); + + return 0; +} -- cgit v1.2.3