Commit 66ee4402 authored by James Zern's avatar James Zern

aom_encoder: enable floating point exceptions

with --enable-debug (CONFIG_DEBUG) when available

BUG=aomedia:388

Change-Id: I5dd0718d6bd0ba17bc1b52d5842e250244d2d1d8
parent 4ab325c3
...@@ -13,9 +13,15 @@ ...@@ -13,9 +13,15 @@
* \brief Provides the high level interface to wrap encoder algorithms. * \brief Provides the high level interface to wrap encoder algorithms.
* *
*/ */
#include "./aom_config.h"
#if HAVE_FEXCEPT
#define _GNU_SOURCE
#include <fenv.h>
#endif
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include "aom_config.h"
#include "aom/internal/aom_codec_internal.h" #include "aom/internal/aom_codec_internal.h"
#define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var) #define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var)
...@@ -168,23 +174,42 @@ aom_codec_err_t aom_codec_enc_config_default(aom_codec_iface_t *iface, ...@@ -168,23 +174,42 @@ aom_codec_err_t aom_codec_enc_config_default(aom_codec_iface_t *iface,
return res; return res;
} }
/* clang-format off */
#define FLOATING_POINT_BEGIN_SCOPE do {
#define FLOATING_POINT_END_SCOPE } while (0);
/* clang-format on */
#if ARCH_X86 || ARCH_X86_64 #if ARCH_X86 || ARCH_X86_64
/* On X86, disable the x87 unit's internal 80 bit precision for better /* On X86, disable the x87 unit's internal 80 bit precision for better
* consistency with the SSE unit's 64 bit precision. * consistency with the SSE unit's 64 bit precision.
*/ */
#include "aom_ports/x86.h" #include "aom_ports/x86.h"
#define FLOATING_POINT_INIT() \ #define FLOATING_POINT_SET_PRECISION \
do { \ unsigned short x87_orig_mode = x87_set_double_precision();
unsigned short x87_orig_mode = x87_set_double_precision(); #define FLOATING_POINT_RESTORE_PRECISION x87_set_control_word(x87_orig_mode);
#define FLOATING_POINT_RESTORE() \
x87_set_control_word(x87_orig_mode); \
} \
while (0)
#else #else
static void FLOATING_POINT_INIT() {} #define FLOATING_POINT_SET_PRECISION
static void FLOATING_POINT_RESTORE() {} #define FLOATING_POINT_RESTORE_PRECISION
#endif #endif // ARCH_X86 || ARCH_X86_64
#if HAVE_FEXCEPT && CONFIG_DEBUG
#define FLOATING_POINT_SET_EXCEPTIONS \
const int float_excepts = feenableexcept(FE_DIVBYZERO);
#define FLOATING_POINT_RESTORE_EXCEPTIONS feenableexcept(float_excepts);
#else
#define FLOATING_POINT_SET_EXCEPTIONS
#define FLOATING_POINT_RESTORE_EXCEPTIONS
#endif // HAVE_FEXCEPT && CONFIG_DEBUG
#define FLOATING_POINT_INIT \
FLOATING_POINT_BEGIN_SCOPE \
FLOATING_POINT_SET_PRECISION \
FLOATING_POINT_SET_EXCEPTIONS
#define FLOATING_POINT_RESTORE \
FLOATING_POINT_RESTORE_EXCEPTIONS \
FLOATING_POINT_RESTORE_PRECISION \
FLOATING_POINT_END_SCOPE
aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img, aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img,
aom_codec_pts_t pts, unsigned long duration, aom_codec_pts_t pts, unsigned long duration,
...@@ -204,7 +229,7 @@ aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img, ...@@ -204,7 +229,7 @@ aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img,
/* Execute in a normalized floating point environment, if the platform /* Execute in a normalized floating point environment, if the platform
* requires it. * requires it.
*/ */
FLOATING_POINT_INIT(); FLOATING_POINT_INIT
if (num_enc == 1) if (num_enc == 1)
res = ctx->iface->enc.encode(get_alg_priv(ctx), img, pts, duration, flags, res = ctx->iface->enc.encode(get_alg_priv(ctx), img, pts, duration, flags,
...@@ -231,7 +256,7 @@ aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img, ...@@ -231,7 +256,7 @@ aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img,
ctx++; ctx++;
} }
FLOATING_POINT_RESTORE(); FLOATING_POINT_RESTORE
} }
return SAVE_STATUS(ctx, res); return SAVE_STATUS(ctx, res);
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#define HAVE_AVX ${HAVE_AVX} #define HAVE_AVX ${HAVE_AVX}
#define HAVE_AVX2 ${HAVE_AVX2} #define HAVE_AVX2 ${HAVE_AVX2}
#define HAVE_AOM_PORTS ${HAVE_AOM_PORTS} #define HAVE_AOM_PORTS ${HAVE_AOM_PORTS}
#define HAVE_FEXCEPT ${HAVE_FEXCEPT}
#define HAVE_PTHREAD_H ${HAVE_PTHREAD_H} #define HAVE_PTHREAD_H ${HAVE_PTHREAD_H}
#define HAVE_UNISTD_H ${HAVE_UNISTD_H} #define HAVE_UNISTD_H ${HAVE_UNISTD_H}
#define CONFIG_DEPENDENCY_TRACKING ${CONFIG_DEPENDENCY_TRACKING} #define CONFIG_DEPENDENCY_TRACKING ${CONFIG_DEPENDENCY_TRACKING}
......
...@@ -36,6 +36,7 @@ set(HAVE_SSE4_1 0 CACHE BOOL "Enables SSE 4.1 optimizations.") ...@@ -36,6 +36,7 @@ set(HAVE_SSE4_1 0 CACHE BOOL "Enables SSE 4.1 optimizations.")
set(HAVE_AVX 0 CACHE BOOL "Enables AVX optimizations.") set(HAVE_AVX 0 CACHE BOOL "Enables AVX optimizations.")
set(HAVE_AVX2 0 CACHE BOOL "Enables AVX2 optimizations.") set(HAVE_AVX2 0 CACHE BOOL "Enables AVX2 optimizations.")
set(HAVE_AOM_PORTS 0 CACHE BOOL "Internal flag, deprecated.") set(HAVE_AOM_PORTS 0 CACHE BOOL "Internal flag, deprecated.")
set(HAVE_FEXCEPT 0 CACHE BOOL "Internal flag, GNU fenv.h present for target.")
set(HAVE_PTHREAD_H 0 CACHE BOOL "Internal flag, target pthread support.") set(HAVE_PTHREAD_H 0 CACHE BOOL "Internal flag, target pthread support.")
set(HAVE_UNISTD_H 0 CACHE BOOL "Internal flag, unistd.h present for target.") set(HAVE_UNISTD_H 0 CACHE BOOL "Internal flag, unistd.h present for target.")
set(CONFIG_DEPENDENCY_TRACKING 1 CACHE BOOL "Internal flag.") set(CONFIG_DEPENDENCY_TRACKING 1 CACHE BOOL "Internal flag.")
......
...@@ -158,6 +158,17 @@ if (CONFIG_ANS AND CONFIG_DAALA_EC) ...@@ -158,6 +158,17 @@ if (CONFIG_ANS AND CONFIG_DAALA_EC)
"CONFIG_ANS and CONFIG_DAALA_EC cannot be enabled together.") "CONFIG_ANS and CONFIG_DAALA_EC cannot be enabled together.")
endif () endif ()
if (NOT MSVC)
aom_push_var(CMAKE_REQUIRED_LIBRARIES "m")
aom_check_c_compiles("fenv_check"
"#define _GNU_SOURCE
#include <fenv.h>
void unused(void) {
(void)feenableexcept(FE_DIVBYZERO | FE_INVALID);
}" HAVE_FEXCEPT)
aom_pop_var(CMAKE_REQUIRED_LIBRARIES)
endif()
# TODO(tomfinegan): consume trailing whitespace after configure_file() when # TODO(tomfinegan): consume trailing whitespace after configure_file() when
# target platform check produces empty INLINE and RESTRICT values (aka empty # target platform check produces empty INLINE and RESTRICT values (aka empty
# values require special casing). # values require special casing).
......
...@@ -21,6 +21,16 @@ set(AOM_C_FAILED_TESTS) ...@@ -21,6 +21,16 @@ set(AOM_C_FAILED_TESTS)
set(AOM_CXX_PASSED_TESTS) set(AOM_CXX_PASSED_TESTS)
set(AOM_CXX_FAILED_TESTS) set(AOM_CXX_FAILED_TESTS)
function(aom_push_var var new_value)
set(SAVED_${var} ${var} PARENT_SCOPE)
set(${var} ${new_value} PARENT_SCOPE)
endfunction ()
function(aom_pop_var var)
set(var ${SAVED_${var}} PARENT_SCOPE)
unset(SAVED_${var} PARENT_SCOPE)
endfunction ()
# Confirms $test_source compiles and stores $test_name in one of # Confirms $test_source compiles and stores $test_name in one of
# $AOM_C_PASSED_TESTS or $AOM_C_FAILED_TESTS depending on out come. When the # $AOM_C_PASSED_TESTS or $AOM_C_FAILED_TESTS depending on out come. When the
# test passes $result_var is set to 1. When it fails $result_var is unset. # test passes $result_var is set to 1. When it fails $result_var is unset.
......
...@@ -238,6 +238,7 @@ ARCH_EXT_LIST=" ...@@ -238,6 +238,7 @@ ARCH_EXT_LIST="
HAVE_LIST=" HAVE_LIST="
${ARCH_EXT_LIST} ${ARCH_EXT_LIST}
aom_ports aom_ports
fexcept
pthread_h pthread_h
unistd_h unistd_h
wxwidgets wxwidgets
...@@ -649,6 +650,12 @@ EOF ...@@ -649,6 +650,12 @@ EOF
check_header unistd.h # for sysconf(3) and friends. check_header unistd.h # for sysconf(3) and friends.
check_header aom/aom_integer.h -I${source_path} && enable_feature aom_ports check_header aom/aom_integer.h -I${source_path} && enable_feature aom_ports
check_ld <<EOF && enable_feature fexcept
#define _GNU_SOURCE
#include <fenv.h>
int main(void) { (void)feenableexcept(FE_DIVBYZERO | FE_INVALID); return 0; }
EOF
} }
process_toolchain() { process_toolchain() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment