summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duvivier <cduvivier@google.com>2012-08-08 15:47:36 -0700
committerChristian Duvivier <cduvivier@google.com>2012-08-08 16:43:48 -0700
commit707b65bd160766f22d82c2c9b3dfc74955c3e2df (patch)
tree553e5d7e8e3dd7eba09f9ab6936d637461fae9e6
parent2056f7e0d8d3fc4fd05e53d199dc15b8779bcb64 (diff)
downloadlibvpx-707b65bd160766f22d82c2c9b3dfc74955c3e2df.tar
libvpx-707b65bd160766f22d82c2c9b3dfc74955c3e2df.tar.gz
libvpx-707b65bd160766f22d82c2c9b3dfc74955c3e2df.tar.bz2
libvpx-707b65bd160766f22d82c2c9b3dfc74955c3e2df.zip
Partial import of "New RTCD implementation" from master branch.
Latest version of all scripts/makefile but rtcd_defs.sh is empty, all existing functions are still selected using the old/current way. Change-Id: Ib92946a48a31d6c8d1d7359eca524bc1d3e66174
-rwxr-xr-xbuild/make/configure.sh17
-rwxr-xr-xbuild/make/rtcd.sh356
-rw-r--r--libs.mk14
-rw-r--r--vp8/common/generic/systemdependent.c3
-rw-r--r--vp8/common/rtcd.c69
-rw-r--r--vp8/common/rtcd_defs.sh6
-rw-r--r--vp8/vp8_common.mk2
7 files changed, 465 insertions, 2 deletions
diff --git a/build/make/configure.sh b/build/make/configure.sh
index 552f8c188..be3477823 100755
--- a/build/make/configure.sh
+++ b/build/make/configure.sh
@@ -389,6 +389,7 @@ LDFLAGS = ${LDFLAGS}
ASFLAGS = ${ASFLAGS}
extralibs = ${extralibs}
AS_SFX = ${AS_SFX:-.asm}
+RTCD_OPTIONS = ${RTCD_OPTIONS}
EOF
if enabled rvct; then cat >> $1 << EOF
@@ -451,8 +452,20 @@ process_common_cmdline() {
;;
--enable-?*|--disable-?*)
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
- echo "${CMDLINE_SELECT} ${ARCH_EXT_LIST}" | grep "^ *$option\$" >/dev/null || die_unknown $opt
- $action $option
+ if echo "${ARCH_EXT_LIST}" | grep "^ *$option\$" >/dev/null; then
+ [ $action = "disable" ] && RTCD_OPTIONS="${RTCD_OPTIONS}${opt} "
+ else
+ echo "${CMDLINE_SELECT}" | grep "^ *$option\$" >/dev/null ||
+ die_unknown $opt
+ fi $action $option
+ ;;
+ --require-?*)
+ eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
+ if echo "${ARCH_EXT_LIST}" none | grep "^ *$option\$" >/dev/null; then
+ RTCD_OPTIONS="${RTCD_OPTIONS}${opt} "
+ else
+ die_unknown $opt
+ fi
;;
--force-enable-?*|--force-disable-?*)
eval `echo "$opt" | sed 's/--force-/action=/;s/-/ option=/;s/-/_/g'`
diff --git a/build/make/rtcd.sh b/build/make/rtcd.sh
new file mode 100755
index 000000000..ddf9e09a4
--- /dev/null
+++ b/build/make/rtcd.sh
@@ -0,0 +1,356 @@
+#!/bin/sh
+self=$0
+
+usage() {
+ cat <<EOF >&2
+Usage: $self [options] FILE
+
+Reads the Run Time CPU Detections definitions from FILE and generates a
+C header file on stdout.
+
+Options:
+ --arch=ARCH Architecture to generate defs for (required)
+ --disable-EXT Disable support for EXT extensions
+ --require-EXT Require support for EXT extensions
+ --sym=SYMBOL Unique symbol to use for RTCD initialization function
+ --config=FILE File with CONFIG_FOO=yes lines to parse
+EOF
+ exit 1
+}
+
+die() {
+ echo "$@" >&2
+ exit 1
+}
+
+die_argument_required() {
+ die "Option $opt requires argument"
+}
+
+for opt; do
+ optval="${opt#*=}"
+ case "$opt" in
+ --arch) die_argument_required;;
+ --arch=*) arch=${optval};;
+ --disable-*) eval "disable_${opt#--disable-}=true";;
+ --require-*) REQUIRES="${REQUIRES}${opt#--require-} ";;
+ --sym) die_argument_required;;
+ --sym=*) symbol=${optval};;
+ --config=*) config_file=${optval};;
+ -h|--help)
+ usage
+ ;;
+ -*)
+ die "Unrecognized option: ${opt%%=*}"
+ ;;
+ *)
+ defs_file="$defs_file $opt"
+ ;;
+ esac
+ shift
+done
+for f in $defs_file; do [ -f "$f" ] || usage; done
+[ -n "$arch" ] || usage
+
+# Import the configuration
+[ -f "$config_file" ] && eval $(grep CONFIG_ "$config_file")
+
+#
+# Routines for the RTCD DSL to call
+#
+prototype() {
+ local rtyp
+ case "$1" in
+ unsigned) rtyp="$1 "; shift;;
+ esac
+ rtyp="${rtyp}$1"
+ local fn="$2"
+ local args="$3"
+
+ eval "${2}_rtyp='$rtyp'"
+ eval "${2}_args='$3'"
+ ALL_FUNCS="$ALL_FUNCS $fn"
+ specialize $fn c
+}
+
+specialize() {
+ local fn="$1"
+ shift
+ for opt in "$@"; do
+ eval "${fn}_${opt}=${fn}_${opt}"
+ done
+}
+
+require() {
+ for fn in $ALL_FUNCS; do
+ for opt in "$@"; do
+ local ofn=$(eval "echo \$${fn}_${opt}")
+ [ -z "$ofn" ] && continue
+
+ # if we already have a default, then we can disable it, as we know
+ # we can do better.
+ local best=$(eval "echo \$${fn}_default")
+ local best_ofn=$(eval "echo \$${best}")
+ [ -n "$best" ] && [ "$best_ofn" != "$ofn" ] && eval "${best}_link=false"
+ eval "${fn}_default=${fn}_${opt}"
+ eval "${fn}_${opt}_link=true"
+ done
+ done
+}
+
+forward_decls() {
+ ALL_FORWARD_DECLS="$ALL_FORWARD_DECLS $1"
+}
+
+#
+# Include the user's directives
+#
+for f in $defs_file; do
+ . $f
+done
+
+#
+# Process the directives according to the command line
+#
+process_forward_decls() {
+ for fn in $ALL_FORWARD_DECLS; do
+ eval $fn
+ done
+}
+
+determine_indirection() {
+ [ "$CONFIG_RUNTIME_CPU_DETECT" = "yes" ] || require $ALL_ARCHS
+ for fn in $ALL_FUNCS; do
+ local n=""
+ local rtyp="$(eval "echo \$${fn}_rtyp")"
+ local args="$(eval "echo \"\$${fn}_args\"")"
+ local dfn="$(eval "echo \$${fn}_default")"
+ dfn=$(eval "echo \$${dfn}")
+ for opt in "$@"; do
+ local ofn=$(eval "echo \$${fn}_${opt}")
+ [ -z "$ofn" ] && continue
+ local link=$(eval "echo \$${fn}_${opt}_link")
+ [ "$link" = "false" ] && continue
+ n="${n}x"
+ done
+ if [ "$n" = "x" ]; then
+ eval "${fn}_indirect=false"
+ else
+ eval "${fn}_indirect=true"
+ fi
+ done
+}
+
+declare_function_pointers() {
+ for fn in $ALL_FUNCS; do
+ local rtyp="$(eval "echo \$${fn}_rtyp")"
+ local args="$(eval "echo \"\$${fn}_args\"")"
+ local dfn="$(eval "echo \$${fn}_default")"
+ dfn=$(eval "echo \$${dfn}")
+ for opt in "$@"; do
+ local ofn=$(eval "echo \$${fn}_${opt}")
+ [ -z "$ofn" ] && continue
+ echo "$rtyp ${ofn}($args);"
+ done
+ if [ "$(eval "echo \$${fn}_indirect")" = "false" ]; then
+ echo "#define ${fn} ${dfn}"
+ else
+ echo "RTCD_EXTERN $rtyp (*${fn})($args);"
+ fi
+ echo
+ done
+}
+
+set_function_pointers() {
+ for fn in $ALL_FUNCS; do
+ local n=""
+ local rtyp="$(eval "echo \$${fn}_rtyp")"
+ local args="$(eval "echo \"\$${fn}_args\"")"
+ local dfn="$(eval "echo \$${fn}_default")"
+ dfn=$(eval "echo \$${dfn}")
+ if $(eval "echo \$${fn}_indirect"); then
+ echo " $fn = $dfn;"
+ for opt in "$@"; do
+ local ofn=$(eval "echo \$${fn}_${opt}")
+ [ -z "$ofn" ] && continue
+ [ "$ofn" = "$dfn" ] && continue;
+ local link=$(eval "echo \$${fn}_${opt}_link")
+ [ "$link" = "false" ] && continue
+ local cond="$(eval "echo \$have_${opt}")"
+ echo " if (${cond}) $fn = $ofn;"
+ done
+ fi
+ echo
+ done
+}
+
+filter() {
+ local filtered
+ for opt in "$@"; do
+ [ -z $(eval "echo \$disable_${opt}") ] && filtered="$filtered $opt"
+ done
+ echo $filtered
+}
+
+#
+# Helper functions for generating the arch specific RTCD files
+#
+common_top() {
+ local outfile_basename=$(basename ${symbol:-rtcd.h})
+ local include_guard=$(echo $outfile_basename | tr '[a-z]' '[A-Z]' | tr -c '[A-Z]' _)
+ cat <<EOF
+#ifndef ${include_guard}
+#define ${include_guard}
+
+#ifdef RTCD_C
+#define RTCD_EXTERN
+#else
+#define RTCD_EXTERN extern
+#endif
+
+$(process_forward_decls)
+
+$(declare_function_pointers c $ALL_ARCHS)
+
+void ${symbol:-rtcd}(void);
+EOF
+}
+
+common_bottom() {
+ cat <<EOF
+#endif
+EOF
+}
+
+x86() {
+ determine_indirection c $ALL_ARCHS
+
+ # Assign the helper variable for each enabled extension
+ for opt in $ALL_ARCHS; do
+ local uc=$(echo $opt | tr '[a-z]' '[A-Z]')
+ eval "have_${opt}=\"flags & HAS_${uc}\""
+ done
+
+ cat <<EOF
+$(common_top)
+
+#ifdef RTCD_C
+#include "vpx_ports/x86.h"
+static void setup_rtcd_internal(void)
+{
+ int flags = x86_simd_caps();
+
+ (void)flags;
+
+$(set_function_pointers c $ALL_ARCHS)
+}
+#endif
+$(common_bottom)
+EOF
+}
+
+arm() {
+ determine_indirection c $ALL_ARCHS
+
+ # Assign the helper variable for each enabled extension
+ for opt in $ALL_ARCHS; do
+ local uc=$(echo $opt | tr '[a-z]' '[A-Z]')
+ eval "have_${opt}=\"flags & HAS_${uc}\""
+ done
+
+ cat <<EOF
+$(common_top)
+#include "vpx_config.h"
+
+#ifdef RTCD_C
+#include "vpx_ports/arm.h"
+static void setup_rtcd_internal(void)
+{
+ int flags = arm_cpu_caps();
+
+ (void)flags;
+
+$(set_function_pointers c $ALL_ARCHS)
+}
+#endif
+$(common_bottom)
+EOF
+}
+
+
+mips() {
+ determine_indirection c $ALL_ARCHS
+ cat <<EOF
+$(common_top)
+#include "vpx_config.h"
+
+#ifdef RTCD_C
+static void setup_rtcd_internal(void)
+{
+$(set_function_pointers c $ALL_ARCHS)
+#if HAVE_DSPR2
+void dsputil_static_init();
+dsputil_static_init();
+#endif
+}
+#endif
+$(common_bottom)
+EOF
+}
+
+unoptimized() {
+ determine_indirection c
+ cat <<EOF
+$(common_top)
+#include "vpx_config.h"
+
+#ifdef RTCD_C
+static void setup_rtcd_internal(void)
+{
+$(set_function_pointers c)
+}
+#endif
+$(common_bottom)
+EOF
+
+}
+#
+# Main Driver
+#
+require c
+case $arch in
+ x86)
+ ALL_ARCHS=$(filter mmx sse sse2 sse3 ssse3 sse4_1)
+ x86
+ ;;
+ x86_64)
+ ALL_ARCHS=$(filter mmx sse sse2 sse3 ssse3 sse4_1)
+ REQUIRES=${REQUIRES:-mmx sse sse2}
+ require $(filter $REQUIRES)
+ x86
+ ;;
+ mips32)
+ ALL_ARCHS=$(filter mips32)
+ dspr2=$([ -f "$config_file" ] && eval echo $(grep HAVE_DSPR2 "$config_file"))
+ HAVE_DSPR2="${dspr2#*=}"
+ if [ "$HAVE_DSPR2" = "yes" ]; then
+ ALL_ARCHS=$(filter mips32 dspr2)
+ fi
+ mips
+ ;;
+ armv5te)
+ ALL_ARCHS=$(filter edsp)
+ arm
+ ;;
+ armv6)
+ ALL_ARCHS=$(filter edsp media)
+ arm
+ ;;
+ armv7)
+ ALL_ARCHS=$(filter edsp media neon)
+ arm
+ ;;
+ *)
+ unoptimized
+ ;;
+esac
diff --git a/libs.mk b/libs.mk
index f904a4a21..674571add 100644
--- a/libs.mk
+++ b/libs.mk
@@ -91,6 +91,7 @@ endif
$(eval $(if $(filter universal%,$(TOOLCHAIN)),LIPO_LIBVPX,BUILD_LIBVPX):=yes)
CODEC_SRCS-$(BUILD_LIBVPX) += build/make/version.sh
+CODEC_SRCS-$(BUILD_LIBVPX) += build/make/rtcd.sh
CODEC_SRCS-$(BUILD_LIBVPX) += vpx/vpx_integer.h
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/asm_offsets.h
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/vpx_timer.h
@@ -185,6 +186,7 @@ vpx.vcproj: $(CODEC_SRCS) vpx.def
PROJECTS-$(BUILD_LIBVPX) += vpx.vcproj
vpx.vcproj: vpx_config.asm
+vpx.vcproj: vpx_rtcd.h
endif
else
@@ -351,6 +353,18 @@ endif
$(shell $(SRC_PATH_BARE)/build/make/version.sh "$(SRC_PATH_BARE)" $(BUILD_PFX)vpx_version.h)
CLEAN-OBJS += $(BUILD_PFX)vpx_version.h
+#
+# Rule to generate runtime cpu detection files
+#
+$(OBJS-yes:.o=.d): vpx_rtcd.h
+vpx_rtcd.h: $(sort $(filter %rtcd_defs.sh,$(CODEC_SRCS)))
+ @echo " [CREATE] $@"
+ $(qexec)$(SRC_PATH_BARE)/build/make/rtcd.sh --arch=$(TGT_ISA) \
+ --sym=vpx_rtcd \
+ --config=$(target)$(if $(FAT_ARCHS),,-$(TOOLCHAIN)).mk \
+ $(RTCD_OPTIONS) $^ > $@
+CLEAN-OBJS += $(BUILD_PFX)vpx_rtcd.h
+
CODEC_DOC_SRCS += vpx/vpx_codec.h \
vpx/vpx_decoder.h \
vpx/vpx_encoder.h \
diff --git a/vp8/common/generic/systemdependent.c b/vp8/common/generic/systemdependent.c
index 1798e6524..b71ef750d 100644
--- a/vp8/common/generic/systemdependent.c
+++ b/vp8/common/generic/systemdependent.c
@@ -10,6 +10,7 @@
#include "vpx_ports/config.h"
+#include "vpx_rtcd.h"
#include "vp8/common/g_common.h"
#include "vp8/common/subpixel.h"
#include "vp8/common/loopfilter.h"
@@ -140,4 +141,6 @@ void vp8_machine_specific_config(VP8_COMMON *ctx) {
#if ARCH_ARM
vp8_arch_arm_common_init(ctx);
#endif
+
+ vpx_rtcd();
}
diff --git a/vp8/common/rtcd.c b/vp8/common/rtcd.c
new file mode 100644
index 000000000..4980f48ad
--- /dev/null
+++ b/vp8/common/rtcd.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2011 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "vpx_config.h"
+#define RTCD_C
+#include "vpx_rtcd.h"
+
+#if CONFIG_MULTITHREAD && HAVE_PTHREAD_H
+#include <pthread.h>
+static void once(void (*func)(void))
+{
+ static pthread_once_t lock = PTHREAD_ONCE_INIT;
+ pthread_once(&lock, func);
+}
+
+
+#elif CONFIG_MULTITHREAD && defined(_WIN32)
+#include <windows.h>
+static void once(void (*func)(void))
+{
+ /* Using a static initializer here rather than InitializeCriticalSection()
+ * since there's no race-free context in which to execute it. Protecting
+ * it with an atomic op like InterlockedCompareExchangePointer introduces
+ * an x86 dependency, and InitOnceExecuteOnce requires Vista.
+ */
+ static CRITICAL_SECTION lock = {(void *)-1, -1, 0, 0, 0, 0};
+ static int done;
+
+ EnterCriticalSection(&lock);
+
+ if (!done)
+ {
+ func();
+ done = 1;
+ }
+
+ LeaveCriticalSection(&lock);
+}
+
+
+#else
+/* No-op version that performs no synchronization. vpx_rtcd() is idempotent,
+ * so as long as your platform provides atomic loads/stores of pointers
+ * no synchronization is strictly necessary.
+ */
+
+static void once(void (*func)(void))
+{
+ static int done;
+
+ if(!done)
+ {
+ func();
+ done = 1;
+ }
+}
+#endif
+
+
+void vpx_rtcd()
+{
+ once(setup_rtcd_internal);
+}
diff --git a/vp8/common/rtcd_defs.sh b/vp8/common/rtcd_defs.sh
new file mode 100644
index 000000000..95148c86f
--- /dev/null
+++ b/vp8/common/rtcd_defs.sh
@@ -0,0 +1,6 @@
+common_forward_decls() {
+cat <<EOF
+struct blockd;
+EOF
+}
+forward_decls common_forward_decls
diff --git a/vp8/vp8_common.mk b/vp8/vp8_common.mk
index c4bd283f8..8c9addc78 100644
--- a/vp8/vp8_common.mk
+++ b/vp8/vp8_common.mk
@@ -52,6 +52,8 @@ VP8_COMMON_SRCS-yes += common/recon.h
VP8_COMMON_SRCS-yes += common/reconinter.h
VP8_COMMON_SRCS-yes += common/reconintra.h
VP8_COMMON_SRCS-yes += common/reconintra4x4.h
+VP8_COMMON_SRCS-yes += common/rtcd.c
+VP8_COMMON_SRCS-yes += common/rtcd_defs.sh
VP8_COMMON_SRCS-yes += common/seg_common.h
VP8_COMMON_SRCS-yes += common/seg_common.c
VP8_COMMON_SRCS-yes += common/setupintrarecon.h