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 @@
* \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 <string.h>
#include "aom_config.h"
#include "aom/internal/aom_codec_internal.h"
#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,
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
/* On X86, disable the x87 unit's internal 80 bit precision for better
* consistency with the SSE unit's 64 bit precision.
*/
#include "aom_ports/x86.h"
#define FLOATING_POINT_INIT() \
do { \
unsigned short x87_orig_mode = x87_set_double_precision();
#define FLOATING_POINT_RESTORE() \
x87_set_control_word(x87_orig_mode); \
} \
while (0)
#define FLOATING_POINT_SET_PRECISION \
unsigned short x87_orig_mode = x87_set_double_precision();
#define FLOATING_POINT_RESTORE_PRECISION x87_set_control_word(x87_orig_mode);
#else
static void FLOATING_POINT_INIT() {}
static void FLOATING_POINT_RESTORE() {}
#endif
#define FLOATING_POINT_SET_PRECISION
#define FLOATING_POINT_RESTORE_PRECISION
#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_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,
/* Execute in a normalized floating point environment, if the platform
* requires it.
*/
FLOATING_POINT_INIT();
FLOATING_POINT_INIT
if (num_enc == 1)
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,
ctx++;
}
FLOATING_POINT_RESTORE();
FLOATING_POINT_RESTORE
}
return SAVE_STATUS(ctx, res);
......
......@@ -36,6 +36,7 @@
#define HAVE_AVX ${HAVE_AVX}
#define HAVE_AVX2 ${HAVE_AVX2}
#define HAVE_AOM_PORTS ${HAVE_AOM_PORTS}
#define HAVE_FEXCEPT ${HAVE_FEXCEPT}
#define HAVE_PTHREAD_H ${HAVE_PTHREAD_H}
#define HAVE_UNISTD_H ${HAVE_UNISTD_H}
#define CONFIG_DEPENDENCY_TRACKING ${CONFIG_DEPENDENCY_TRACKING}
......
......@@ -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_AVX2 0 CACHE BOOL "Enables AVX2 optimizations.")
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_UNISTD_H 0 CACHE BOOL "Internal flag, unistd.h present for target.")
set(CONFIG_DEPENDENCY_TRACKING 1 CACHE BOOL "Internal flag.")
......
......@@ -158,6 +158,17 @@ if (CONFIG_ANS AND CONFIG_DAALA_EC)
"CONFIG_ANS and CONFIG_DAALA_EC cannot be enabled together.")
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
# target platform check produces empty INLINE and RESTRICT values (aka empty
# values require special casing).
......
......@@ -21,6 +21,16 @@ set(AOM_C_FAILED_TESTS)
set(AOM_CXX_PASSED_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
# $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.
......
......@@ -238,6 +238,7 @@ ARCH_EXT_LIST="
HAVE_LIST="
${ARCH_EXT_LIST}
aom_ports
fexcept
pthread_h
unistd_h
wxwidgets
......@@ -649,6 +650,12 @@ EOF
check_header unistd.h # for sysconf(3) and friends.
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() {
......
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