Merge pull request #548 from baldurk/vs2010-compile-fixes
VS2010 compile fixes
This commit is contained in:
@@ -75,6 +75,7 @@ public:
|
|||||||
|
|
||||||
#if !defined (use_cpp11)
|
#if !defined (use_cpp11)
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
class spirvbin_t : public spirvbin_base_t
|
class spirvbin_t : public spirvbin_base_t
|
||||||
|
|||||||
@@ -797,7 +797,7 @@ Id Builder::makeFloat16Constant(float f16, bool specConstant)
|
|||||||
|
|
||||||
spvutils::HexFloat<spvutils::FloatProxy<float>> fVal(f16);
|
spvutils::HexFloat<spvutils::FloatProxy<float>> fVal(f16);
|
||||||
spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>> f16Val(0);
|
spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>> f16Val(0);
|
||||||
fVal.castTo(f16Val, spvutils::round_direction::kToZero);
|
fVal.castTo(f16Val, spvutils::kRoundToZero);
|
||||||
|
|
||||||
unsigned value = f16Val.value().getAsFloat().get_value();
|
unsigned value = f16Val.value().getAsFloat().get_value();
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,19 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER < 1700
|
||||||
|
namespace std {
|
||||||
|
bool isnan(double f)
|
||||||
|
{
|
||||||
|
return ::_isnan(f) != 0;
|
||||||
|
}
|
||||||
|
bool isinf(double f)
|
||||||
|
{
|
||||||
|
return ::_finite(f) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "bitutils.h"
|
#include "bitutils.h"
|
||||||
|
|
||||||
namespace spvutils {
|
namespace spvutils {
|
||||||
@@ -30,7 +43,7 @@ namespace spvutils {
|
|||||||
class Float16 {
|
class Float16 {
|
||||||
public:
|
public:
|
||||||
Float16(uint16_t v) : val(v) {}
|
Float16(uint16_t v) : val(v) {}
|
||||||
Float16() = default;
|
Float16() {}
|
||||||
static bool isNan(const Float16& val) {
|
static bool isNan(const Float16& val) {
|
||||||
return ((val.val & 0x7C00) == 0x7C00) && ((val.val & 0x3FF) != 0);
|
return ((val.val & 0x7C00) == 0x7C00) && ((val.val & 0x3FF) != 0);
|
||||||
}
|
}
|
||||||
@@ -56,12 +69,12 @@ class Float16 {
|
|||||||
// a value is Nan.
|
// a value is Nan.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct FloatProxyTraits {
|
struct FloatProxyTraits {
|
||||||
using uint_type = void;
|
typedef void uint_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct FloatProxyTraits<float> {
|
struct FloatProxyTraits<float> {
|
||||||
using uint_type = uint32_t;
|
typedef uint32_t uint_type;
|
||||||
static bool isNan(float f) { return std::isnan(f); }
|
static bool isNan(float f) { return std::isnan(f); }
|
||||||
// Returns true if the given value is any kind of infinity.
|
// Returns true if the given value is any kind of infinity.
|
||||||
static bool isInfinity(float f) { return std::isinf(f); }
|
static bool isInfinity(float f) { return std::isinf(f); }
|
||||||
@@ -73,7 +86,7 @@ struct FloatProxyTraits<float> {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct FloatProxyTraits<double> {
|
struct FloatProxyTraits<double> {
|
||||||
using uint_type = uint64_t;
|
typedef uint64_t uint_type;
|
||||||
static bool isNan(double f) { return std::isnan(f); }
|
static bool isNan(double f) { return std::isnan(f); }
|
||||||
// Returns true if the given value is any kind of infinity.
|
// Returns true if the given value is any kind of infinity.
|
||||||
static bool isInfinity(double f) { return std::isinf(f); }
|
static bool isInfinity(double f) { return std::isinf(f); }
|
||||||
@@ -85,7 +98,7 @@ struct FloatProxyTraits<double> {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct FloatProxyTraits<Float16> {
|
struct FloatProxyTraits<Float16> {
|
||||||
using uint_type = uint16_t;
|
typedef uint16_t uint_type;
|
||||||
static bool isNan(Float16 f) { return Float16::isNan(f); }
|
static bool isNan(Float16 f) { return Float16::isNan(f); }
|
||||||
// Returns true if the given value is any kind of infinity.
|
// Returns true if the given value is any kind of infinity.
|
||||||
static bool isInfinity(Float16 f) { return Float16::isInfinity(f); }
|
static bool isInfinity(Float16 f) { return Float16::isInfinity(f); }
|
||||||
@@ -101,11 +114,11 @@ struct FloatProxyTraits<Float16> {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class FloatProxy {
|
class FloatProxy {
|
||||||
public:
|
public:
|
||||||
using uint_type = typename FloatProxyTraits<T>::uint_type;
|
typedef typename FloatProxyTraits<T>::uint_type uint_type;
|
||||||
|
|
||||||
// Since this is to act similar to the normal floats,
|
// Since this is to act similar to the normal floats,
|
||||||
// do not initialize the data by default.
|
// do not initialize the data by default.
|
||||||
FloatProxy() = default;
|
FloatProxy() {}
|
||||||
|
|
||||||
// Intentionally non-explicit. This is a proxy type so
|
// Intentionally non-explicit. This is a proxy type so
|
||||||
// implicit conversions allow us to use it more transparently.
|
// implicit conversions allow us to use it more transparently.
|
||||||
@@ -164,13 +177,13 @@ std::istream& operator>>(std::istream& is, FloatProxy<T>& value) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct HexFloatTraits {
|
struct HexFloatTraits {
|
||||||
// Integer type that can store this hex-float.
|
// Integer type that can store this hex-float.
|
||||||
using uint_type = void;
|
typedef void uint_type;
|
||||||
// Signed integer type that can store this hex-float.
|
// Signed integer type that can store this hex-float.
|
||||||
using int_type = void;
|
typedef void int_type;
|
||||||
// The numerical type that this HexFloat represents.
|
// The numerical type that this HexFloat represents.
|
||||||
using underlying_type = void;
|
typedef void underlying_type;
|
||||||
// The type needed to construct the underlying type.
|
// The type needed to construct the underlying type.
|
||||||
using native_type = void;
|
typedef void native_type;
|
||||||
// The number of bits that are actually relevant in the uint_type.
|
// The number of bits that are actually relevant in the uint_type.
|
||||||
// This allows us to deal with, for example, 24-bit values in a 32-bit
|
// This allows us to deal with, for example, 24-bit values in a 32-bit
|
||||||
// integer.
|
// integer.
|
||||||
@@ -188,10 +201,10 @@ struct HexFloatTraits {
|
|||||||
// 1 sign bit, 8 exponent bits, 23 fractional bits.
|
// 1 sign bit, 8 exponent bits, 23 fractional bits.
|
||||||
template <>
|
template <>
|
||||||
struct HexFloatTraits<FloatProxy<float>> {
|
struct HexFloatTraits<FloatProxy<float>> {
|
||||||
using uint_type = uint32_t;
|
typedef uint32_t uint_type;
|
||||||
using int_type = int32_t;
|
typedef int32_t int_type;
|
||||||
using underlying_type = FloatProxy<float>;
|
typedef FloatProxy<float> underlying_type;
|
||||||
using native_type = float;
|
typedef float native_type;
|
||||||
static const uint_type num_used_bits = 32;
|
static const uint_type num_used_bits = 32;
|
||||||
static const uint_type num_exponent_bits = 8;
|
static const uint_type num_exponent_bits = 8;
|
||||||
static const uint_type num_fraction_bits = 23;
|
static const uint_type num_fraction_bits = 23;
|
||||||
@@ -202,10 +215,10 @@ struct HexFloatTraits<FloatProxy<float>> {
|
|||||||
// 1 sign bit, 11 exponent bits, 52 fractional bits.
|
// 1 sign bit, 11 exponent bits, 52 fractional bits.
|
||||||
template <>
|
template <>
|
||||||
struct HexFloatTraits<FloatProxy<double>> {
|
struct HexFloatTraits<FloatProxy<double>> {
|
||||||
using uint_type = uint64_t;
|
typedef uint64_t uint_type;
|
||||||
using int_type = int64_t;
|
typedef int64_t int_type;
|
||||||
using underlying_type = FloatProxy<double>;
|
typedef FloatProxy<double> underlying_type;
|
||||||
using native_type = double;
|
typedef double native_type;
|
||||||
static const uint_type num_used_bits = 64;
|
static const uint_type num_used_bits = 64;
|
||||||
static const uint_type num_exponent_bits = 11;
|
static const uint_type num_exponent_bits = 11;
|
||||||
static const uint_type num_fraction_bits = 52;
|
static const uint_type num_fraction_bits = 52;
|
||||||
@@ -216,22 +229,21 @@ struct HexFloatTraits<FloatProxy<double>> {
|
|||||||
// 1 sign bit, 5 exponent bits, 10 fractional bits.
|
// 1 sign bit, 5 exponent bits, 10 fractional bits.
|
||||||
template <>
|
template <>
|
||||||
struct HexFloatTraits<FloatProxy<Float16>> {
|
struct HexFloatTraits<FloatProxy<Float16>> {
|
||||||
using uint_type = uint16_t;
|
typedef uint16_t uint_type;
|
||||||
using int_type = int16_t;
|
typedef int16_t int_type;
|
||||||
using underlying_type = uint16_t;
|
typedef uint16_t underlying_type;
|
||||||
using native_type = uint16_t;
|
typedef uint16_t native_type;
|
||||||
static const uint_type num_used_bits = 16;
|
static const uint_type num_used_bits = 16;
|
||||||
static const uint_type num_exponent_bits = 5;
|
static const uint_type num_exponent_bits = 5;
|
||||||
static const uint_type num_fraction_bits = 10;
|
static const uint_type num_fraction_bits = 10;
|
||||||
static const uint_type exponent_bias = 15;
|
static const uint_type exponent_bias = 15;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class round_direction {
|
enum round_direction {
|
||||||
kToZero,
|
kRoundToZero,
|
||||||
kToNearestEven,
|
kRoundToNearestEven,
|
||||||
kToPositiveInfinity,
|
kRoundToPositiveInfinity,
|
||||||
kToNegativeInfinity,
|
kRoundToNegativeInfinity
|
||||||
max = kToNegativeInfinity
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Template class that houses a floating pointer number.
|
// Template class that houses a floating pointer number.
|
||||||
@@ -240,10 +252,10 @@ enum class round_direction {
|
|||||||
template <typename T, typename Traits = HexFloatTraits<T>>
|
template <typename T, typename Traits = HexFloatTraits<T>>
|
||||||
class HexFloat {
|
class HexFloat {
|
||||||
public:
|
public:
|
||||||
using uint_type = typename Traits::uint_type;
|
typedef typename Traits::uint_type uint_type;
|
||||||
using int_type = typename Traits::int_type;
|
typedef typename Traits::int_type int_type;
|
||||||
using underlying_type = typename Traits::underlying_type;
|
typedef typename Traits::underlying_type underlying_type;
|
||||||
using native_type = typename Traits::native_type;
|
typedef typename Traits::native_type native_type;
|
||||||
|
|
||||||
explicit HexFloat(T f) : value_(f) {}
|
explicit HexFloat(T f) : value_(f) {}
|
||||||
|
|
||||||
@@ -444,33 +456,23 @@ class HexFloat {
|
|||||||
// constant_number < 0? 0: constant_number
|
// constant_number < 0? 0: constant_number
|
||||||
// These convert the negative left-shifts into right shifts.
|
// These convert the negative left-shifts into right shifts.
|
||||||
|
|
||||||
template <int_type N, typename enable = void>
|
template <typename int_type>
|
||||||
struct negatable_left_shift {
|
uint_type negatable_left_shift(int_type N, uint_type val)
|
||||||
static uint_type val(uint_type val) {
|
{
|
||||||
return static_cast<uint_type>(val >> -N);
|
if(N >= 0)
|
||||||
}
|
return val << N;
|
||||||
};
|
|
||||||
|
|
||||||
template <int_type N>
|
return val >> -N;
|
||||||
struct negatable_left_shift<N, typename std::enable_if<N >= 0>::type> {
|
}
|
||||||
static uint_type val(uint_type val) {
|
|
||||||
return static_cast<uint_type>(val << N);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int_type N, typename enable = void>
|
template <typename int_type>
|
||||||
struct negatable_right_shift {
|
uint_type negatable_right_shift(int_type N, uint_type val)
|
||||||
static uint_type val(uint_type val) {
|
{
|
||||||
return static_cast<uint_type>(val << -N);
|
if(N >= 0)
|
||||||
}
|
return val >> N;
|
||||||
};
|
|
||||||
|
|
||||||
template <int_type N>
|
return val << -N;
|
||||||
struct negatable_right_shift<N, typename std::enable_if<N >= 0>::type> {
|
}
|
||||||
static uint_type val(uint_type val) {
|
|
||||||
return static_cast<uint_type>(val >> N);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns the significand, rounded to fit in a significand in
|
// Returns the significand, rounded to fit in a significand in
|
||||||
// other_T. This is shifted so that the most significant
|
// other_T. This is shifted so that the most significant
|
||||||
@@ -479,7 +481,7 @@ class HexFloat {
|
|||||||
template <typename other_T>
|
template <typename other_T>
|
||||||
typename other_T::uint_type getRoundedNormalizedSignificand(
|
typename other_T::uint_type getRoundedNormalizedSignificand(
|
||||||
round_direction dir, bool* carry_bit) {
|
round_direction dir, bool* carry_bit) {
|
||||||
using other_uint_type = typename other_T::uint_type;
|
typedef typename other_T::uint_type other_uint_type;
|
||||||
static const int_type num_throwaway_bits =
|
static const int_type num_throwaway_bits =
|
||||||
static_cast<int_type>(num_fraction_bits) -
|
static_cast<int_type>(num_fraction_bits) -
|
||||||
static_cast<int_type>(other_T::num_fraction_bits);
|
static_cast<int_type>(other_T::num_fraction_bits);
|
||||||
@@ -487,11 +489,11 @@ class HexFloat {
|
|||||||
static const uint_type last_significant_bit =
|
static const uint_type last_significant_bit =
|
||||||
(num_throwaway_bits < 0)
|
(num_throwaway_bits < 0)
|
||||||
? 0
|
? 0
|
||||||
: negatable_left_shift<num_throwaway_bits>::val(1u);
|
: negatable_left_shift(num_throwaway_bits, 1u);
|
||||||
static const uint_type first_rounded_bit =
|
static const uint_type first_rounded_bit =
|
||||||
(num_throwaway_bits < 1)
|
(num_throwaway_bits < 1)
|
||||||
? 0
|
? 0
|
||||||
: negatable_left_shift<num_throwaway_bits - 1>::val(1u);
|
: negatable_left_shift(num_throwaway_bits - 1, 1u);
|
||||||
|
|
||||||
static const uint_type throwaway_mask_bits =
|
static const uint_type throwaway_mask_bits =
|
||||||
num_throwaway_bits > 0 ? num_throwaway_bits : 0;
|
num_throwaway_bits > 0 ? num_throwaway_bits : 0;
|
||||||
@@ -513,22 +515,22 @@ class HexFloat {
|
|||||||
// do.
|
// do.
|
||||||
if ((significand & throwaway_mask) == 0) {
|
if ((significand & throwaway_mask) == 0) {
|
||||||
return static_cast<other_uint_type>(
|
return static_cast<other_uint_type>(
|
||||||
negatable_right_shift<num_throwaway_bits>::val(significand));
|
negatable_right_shift(num_throwaway_bits, significand));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool round_away_from_zero = false;
|
bool round_away_from_zero = false;
|
||||||
// We actually have to narrow the significand here, so we have to follow the
|
// We actually have to narrow the significand here, so we have to follow the
|
||||||
// rounding rules.
|
// rounding rules.
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
case round_direction::kToZero:
|
case kRoundToZero:
|
||||||
break;
|
break;
|
||||||
case round_direction::kToPositiveInfinity:
|
case kRoundToPositiveInfinity:
|
||||||
round_away_from_zero = !isNegative();
|
round_away_from_zero = !isNegative();
|
||||||
break;
|
break;
|
||||||
case round_direction::kToNegativeInfinity:
|
case kRoundToNegativeInfinity:
|
||||||
round_away_from_zero = isNegative();
|
round_away_from_zero = isNegative();
|
||||||
break;
|
break;
|
||||||
case round_direction::kToNearestEven:
|
case kRoundToNearestEven:
|
||||||
// Have to round down, round bit is 0
|
// Have to round down, round bit is 0
|
||||||
if ((first_rounded_bit & significand) == 0) {
|
if ((first_rounded_bit & significand) == 0) {
|
||||||
break;
|
break;
|
||||||
@@ -550,11 +552,11 @@ class HexFloat {
|
|||||||
|
|
||||||
if (round_away_from_zero) {
|
if (round_away_from_zero) {
|
||||||
return static_cast<other_uint_type>(
|
return static_cast<other_uint_type>(
|
||||||
negatable_right_shift<num_throwaway_bits>::val(incrementSignificand(
|
negatable_right_shift(num_throwaway_bits, incrementSignificand(
|
||||||
significand, last_significant_bit, carry_bit)));
|
significand, last_significant_bit, carry_bit)));
|
||||||
} else {
|
} else {
|
||||||
return static_cast<other_uint_type>(
|
return static_cast<other_uint_type>(
|
||||||
negatable_right_shift<num_throwaway_bits>::val(significand));
|
negatable_right_shift(num_throwaway_bits, significand));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,9 +610,9 @@ class HexFloat {
|
|||||||
if (is_nan) {
|
if (is_nan) {
|
||||||
typename other_T::uint_type shifted_significand;
|
typename other_T::uint_type shifted_significand;
|
||||||
shifted_significand = static_cast<typename other_T::uint_type>(
|
shifted_significand = static_cast<typename other_T::uint_type>(
|
||||||
negatable_left_shift<
|
negatable_left_shift(
|
||||||
static_cast<int_type>(other_T::num_fraction_bits) -
|
static_cast<int_type>(other_T::num_fraction_bits) -
|
||||||
static_cast<int_type>(num_fraction_bits)>::val(significand));
|
static_cast<int_type>(num_fraction_bits), significand));
|
||||||
|
|
||||||
// We are some sort of Nan. We try to keep the bit-pattern of the Nan
|
// We are some sort of Nan. We try to keep the bit-pattern of the Nan
|
||||||
// as close as possible. If we had to shift off bits so we are 0, then we
|
// as close as possible. If we had to shift off bits so we are 0, then we
|
||||||
@@ -623,9 +625,9 @@ class HexFloat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool round_underflow_up =
|
bool round_underflow_up =
|
||||||
isNegative() ? round_dir == round_direction::kToNegativeInfinity
|
isNegative() ? round_dir == kRoundToNegativeInfinity
|
||||||
: round_dir == round_direction::kToPositiveInfinity;
|
: round_dir == kRoundToPositiveInfinity;
|
||||||
using other_int_type = typename other_T::int_type;
|
typedef typename other_T::int_type other_int_type;
|
||||||
// setFromSignUnbiasedExponentAndNormalizedSignificand will
|
// setFromSignUnbiasedExponentAndNormalizedSignificand will
|
||||||
// zero out any underflowing value (but retain the sign).
|
// zero out any underflowing value (but retain the sign).
|
||||||
other.setFromSignUnbiasedExponentAndNormalizedSignificand(
|
other.setFromSignUnbiasedExponentAndNormalizedSignificand(
|
||||||
@@ -664,9 +666,9 @@ inline uint8_t get_nibble_from_character(int character) {
|
|||||||
// Outputs the given HexFloat to the stream.
|
// Outputs the given HexFloat to the stream.
|
||||||
template <typename T, typename Traits>
|
template <typename T, typename Traits>
|
||||||
std::ostream& operator<<(std::ostream& os, const HexFloat<T, Traits>& value) {
|
std::ostream& operator<<(std::ostream& os, const HexFloat<T, Traits>& value) {
|
||||||
using HF = HexFloat<T, Traits>;
|
typedef HexFloat<T, Traits> HF;
|
||||||
using uint_type = typename HF::uint_type;
|
typedef typename HF::uint_type uint_type;
|
||||||
using int_type = typename HF::int_type;
|
typedef typename HF::int_type int_type;
|
||||||
|
|
||||||
static_assert(HF::num_used_bits != 0,
|
static_assert(HF::num_used_bits != 0,
|
||||||
"num_used_bits must be non-zero for a valid float");
|
"num_used_bits must be non-zero for a valid float");
|
||||||
@@ -745,7 +747,7 @@ inline bool RejectParseDueToLeadingSign(std::istream& is, bool negate_value,
|
|||||||
if (next_char == '-' || next_char == '+') {
|
if (next_char == '-' || next_char == '+') {
|
||||||
// Fail the parse. Emulate standard behaviour by setting the value to
|
// Fail the parse. Emulate standard behaviour by setting the value to
|
||||||
// the zero value, and set the fail bit on the stream.
|
// the zero value, and set the fail bit on the stream.
|
||||||
value = HexFloat<T, Traits>(typename HexFloat<T, Traits>::uint_type{0});
|
value = HexFloat<T, Traits>(typename HexFloat<T, Traits>::uint_type(0));
|
||||||
is.setstate(std::ios_base::failbit);
|
is.setstate(std::ios_base::failbit);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -777,7 +779,7 @@ inline std::istream& ParseNormalFloat(std::istream& is, bool negate_value,
|
|||||||
value.set_value(val);
|
value.set_value(val);
|
||||||
// In the failure case, map -0.0 to 0.0.
|
// In the failure case, map -0.0 to 0.0.
|
||||||
if (is.fail() && value.getUnsignedBits() == 0u) {
|
if (is.fail() && value.getUnsignedBits() == 0u) {
|
||||||
value = HexFloat<T, Traits>(typename HexFloat<T, Traits>::uint_type{0});
|
value = HexFloat<T, Traits>(typename HexFloat<T, Traits>::uint_type(0));
|
||||||
}
|
}
|
||||||
if (val.isInfinity()) {
|
if (val.isInfinity()) {
|
||||||
// Fail the parse. Emulate standard behaviour by setting the value to
|
// Fail the parse. Emulate standard behaviour by setting the value to
|
||||||
@@ -812,7 +814,7 @@ ParseNormalFloat<FloatProxy<Float16>, HexFloatTraits<FloatProxy<Float16>>>(
|
|||||||
|
|
||||||
// Then convert to 16-bit float, saturating at infinities, and
|
// Then convert to 16-bit float, saturating at infinities, and
|
||||||
// rounding toward zero.
|
// rounding toward zero.
|
||||||
float_val.castTo(value, round_direction::kToZero);
|
float_val.castTo(value, kRoundToZero);
|
||||||
|
|
||||||
// Overflow on 16-bit behaves the same as for 32- and 64-bit: set the
|
// Overflow on 16-bit behaves the same as for 32- and 64-bit: set the
|
||||||
// fail bit and set the lowest or highest value.
|
// fail bit and set the lowest or highest value.
|
||||||
|
|||||||
@@ -673,11 +673,11 @@ void CompileAndLinkShaderFiles()
|
|||||||
// they are all getting linked together.)
|
// they are all getting linked together.)
|
||||||
glslang::TWorkItem* workItem;
|
glslang::TWorkItem* workItem;
|
||||||
while (Worklist.remove(workItem)) {
|
while (Worklist.remove(workItem)) {
|
||||||
ShaderCompUnit compUnit = {
|
ShaderCompUnit compUnit(
|
||||||
FindLanguage(workItem->name),
|
FindLanguage(workItem->name),
|
||||||
workItem->name,
|
workItem->name,
|
||||||
ReadFileData(workItem->name.c_str())
|
ReadFileData(workItem->name.c_str())
|
||||||
};
|
);
|
||||||
|
|
||||||
if (! compUnit.text) {
|
if (! compUnit.text) {
|
||||||
usage();
|
usage();
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ inline long long int strtoll (const char* str, char** endptr, int base)
|
|||||||
{
|
{
|
||||||
return _strtoi64(str, endptr, base);
|
return _strtoi64(str, endptr, base);
|
||||||
}
|
}
|
||||||
|
inline unsigned long long int strtoull (const char* str, char** endptr, int base)
|
||||||
|
{
|
||||||
|
return _strtoui64(str, endptr, base);
|
||||||
|
}
|
||||||
inline long long int atoll (const char* str)
|
inline long long int atoll (const char* str)
|
||||||
{
|
{
|
||||||
return strtoll(str, NULL, 10);
|
return strtoll(str, NULL, 10);
|
||||||
|
|||||||
@@ -361,7 +361,7 @@ const TFunction* TParseContextBase::selectFunction(
|
|||||||
return viableCandidates.front();
|
return viableCandidates.front();
|
||||||
|
|
||||||
// 4. find best...
|
// 4. find best...
|
||||||
auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2){
|
auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
|
||||||
// is call -> can2 better than call -> can1 for any parameter
|
// is call -> can2 better than call -> can1 for any parameter
|
||||||
bool hasBetterParam = false;
|
bool hasBetterParam = false;
|
||||||
for (int param = 0; param < call.getParamCount(); ++param) {
|
for (int param = 0; param < call.getParamCount(); ++param) {
|
||||||
|
|||||||
@@ -4873,7 +4873,7 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu
|
|||||||
symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
|
symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
|
||||||
|
|
||||||
// can 'from' convert to 'to'?
|
// can 'from' convert to 'to'?
|
||||||
const auto convertible = [this](const TType& from, const TType& to) {
|
const auto convertible = [this](const TType& from, const TType& to) -> bool {
|
||||||
if (from == to)
|
if (from == to)
|
||||||
return true;
|
return true;
|
||||||
if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
|
if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
|
||||||
@@ -4884,7 +4884,7 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu
|
|||||||
// Is 'to2' a better conversion than 'to1'?
|
// Is 'to2' a better conversion than 'to1'?
|
||||||
// Ties should not be considered as better.
|
// Ties should not be considered as better.
|
||||||
// Assumes 'convertible' already said true.
|
// Assumes 'convertible' already said true.
|
||||||
const auto better = [](const TType& from, const TType& to1, const TType& to2) {
|
const auto better = [](const TType& from, const TType& to1, const TType& to2) -> bool {
|
||||||
// 1. exact match
|
// 1. exact match
|
||||||
if (from == to2)
|
if (from == to2)
|
||||||
return from != to1;
|
return from != to1;
|
||||||
|
|||||||
@@ -690,10 +690,10 @@ TEST(HexFloatOperationTests, NonRounding) {
|
|||||||
bool carry_bit = false;
|
bool carry_bit = false;
|
||||||
|
|
||||||
spvutils::round_direction rounding[] = {
|
spvutils::round_direction rounding[] = {
|
||||||
spvutils::round_direction::kToZero,
|
spvutils::kRoundToZero,
|
||||||
spvutils::round_direction::kToNearestEven,
|
spvutils::kRoundToNearestEven,
|
||||||
spvutils::round_direction::kToPositiveInfinity,
|
spvutils::kRoundToPositiveInfinity,
|
||||||
spvutils::round_direction::kToNegativeInfinity};
|
spvutils::kRoundToNegativeInfinity};
|
||||||
|
|
||||||
// Everything fits, so this should be straight-forward
|
// Everything fits, so this should be straight-forward
|
||||||
for (spvutils::round_direction round : rounding) {
|
for (spvutils::round_direction round : rounding) {
|
||||||
@@ -725,7 +725,6 @@ TEST(HexFloatOperationTests, NonRounding) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using RD = spvutils::round_direction;
|
|
||||||
struct RoundSignificandCase {
|
struct RoundSignificandCase {
|
||||||
float source_float;
|
float source_float;
|
||||||
std::pair<int16_t, bool> expected_results;
|
std::pair<int16_t, bool> expected_results;
|
||||||
@@ -751,49 +750,49 @@ TEST_P(HexFloatRoundTest, RoundDownToFP16) {
|
|||||||
INSTANTIATE_TEST_CASE_P(F32ToF16, HexFloatRoundTest,
|
INSTANTIATE_TEST_CASE_P(F32ToF16, HexFloatRoundTest,
|
||||||
::testing::ValuesIn(std::vector<RoundSignificandCase>(
|
::testing::ValuesIn(std::vector<RoundSignificandCase>(
|
||||||
{
|
{
|
||||||
{float_fractions({0}), std::make_pair(half_bits_set({}), false), RD::kToZero},
|
{float_fractions({0}), std::make_pair(half_bits_set({}), false), spvutils::kRoundToZero},
|
||||||
{float_fractions({0}), std::make_pair(half_bits_set({}), false), RD::kToNearestEven},
|
{float_fractions({0}), std::make_pair(half_bits_set({}), false), spvutils::kRoundToNearestEven},
|
||||||
{float_fractions({0}), std::make_pair(half_bits_set({}), false), RD::kToPositiveInfinity},
|
{float_fractions({0}), std::make_pair(half_bits_set({}), false), spvutils::kRoundToPositiveInfinity},
|
||||||
{float_fractions({0}), std::make_pair(half_bits_set({}), false), RD::kToNegativeInfinity},
|
{float_fractions({0}), std::make_pair(half_bits_set({}), false), spvutils::kRoundToNegativeInfinity},
|
||||||
{float_fractions({0, 1}), std::make_pair(half_bits_set({0}), false), RD::kToZero},
|
{float_fractions({0, 1}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero},
|
||||||
|
|
||||||
{float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), RD::kToZero},
|
{float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero},
|
||||||
{float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0, 9}), false), RD::kToPositiveInfinity},
|
{float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToPositiveInfinity},
|
||||||
{float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), RD::kToNegativeInfinity},
|
{float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToNegativeInfinity},
|
||||||
{float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), RD::kToNearestEven},
|
{float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToNearestEven},
|
||||||
|
|
||||||
{float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 9}), false), RD::kToZero},
|
{float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToZero},
|
||||||
{float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 8}), false), RD::kToPositiveInfinity},
|
{float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 8}), false), spvutils::kRoundToPositiveInfinity},
|
||||||
{float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 9}), false), RD::kToNegativeInfinity},
|
{float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNegativeInfinity},
|
||||||
{float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 8}), false), RD::kToNearestEven},
|
{float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 8}), false), spvutils::kRoundToNearestEven},
|
||||||
|
|
||||||
{float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), RD::kToZero},
|
{float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero},
|
||||||
{float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), RD::kToPositiveInfinity},
|
{float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToPositiveInfinity},
|
||||||
{float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), RD::kToNegativeInfinity},
|
{float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToNegativeInfinity},
|
||||||
{float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), RD::kToNearestEven},
|
{float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNearestEven},
|
||||||
|
|
||||||
{-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), RD::kToZero},
|
{-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero},
|
||||||
{-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), RD::kToPositiveInfinity},
|
{-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToPositiveInfinity},
|
||||||
{-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), RD::kToNegativeInfinity},
|
{-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNegativeInfinity},
|
||||||
{-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), RD::kToNearestEven},
|
{-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNearestEven},
|
||||||
|
|
||||||
{float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0}), false), RD::kToZero},
|
{float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero},
|
||||||
{float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0, 9}), false), RD::kToPositiveInfinity},
|
{float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToPositiveInfinity},
|
||||||
{float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0}), false), RD::kToNegativeInfinity},
|
{float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToNegativeInfinity},
|
||||||
{float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0, 9}), false), RD::kToNearestEven},
|
{float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNearestEven},
|
||||||
|
|
||||||
// Carries
|
// Carries
|
||||||
{float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), false), RD::kToZero},
|
{float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), false), spvutils::kRoundToZero},
|
||||||
{float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({}), true), RD::kToPositiveInfinity},
|
{float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({}), true), spvutils::kRoundToPositiveInfinity},
|
||||||
{float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), false), RD::kToNegativeInfinity},
|
{float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), false), spvutils::kRoundToNegativeInfinity},
|
||||||
{float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({}), true), RD::kToNearestEven},
|
{float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({}), true), spvutils::kRoundToNearestEven},
|
||||||
|
|
||||||
// Cases where original number was denorm. Note: this should have no effect
|
// Cases where original number was denorm. Note: this should have no effect
|
||||||
// the number is pre-normalized.
|
// the number is pre-normalized.
|
||||||
{static_cast<float>(ldexp(float_fractions({0, 1, 11, 13}), -128)), std::make_pair(half_bits_set({0}), false), RD::kToZero},
|
{static_cast<float>(ldexp(float_fractions({0, 1, 11, 13}), -128)), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero},
|
||||||
{static_cast<float>(ldexp(float_fractions({0, 1, 11, 13}), -129)), std::make_pair(half_bits_set({0, 9}), false), RD::kToPositiveInfinity},
|
{static_cast<float>(ldexp(float_fractions({0, 1, 11, 13}), -129)), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToPositiveInfinity},
|
||||||
{static_cast<float>(ldexp(float_fractions({0, 1, 11, 13}), -131)), std::make_pair(half_bits_set({0}), false), RD::kToNegativeInfinity},
|
{static_cast<float>(ldexp(float_fractions({0, 1, 11, 13}), -131)), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToNegativeInfinity},
|
||||||
{static_cast<float>(ldexp(float_fractions({0, 1, 11, 13}), -130)), std::make_pair(half_bits_set({0, 9}), false), RD::kToNearestEven},
|
{static_cast<float>(ldexp(float_fractions({0, 1, 11, 13}), -130)), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNearestEven},
|
||||||
})),);
|
})),);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
@@ -810,10 +809,10 @@ TEST_P(HexFloatRoundUpSignificandTest, Widening) {
|
|||||||
bool carry_bit = false;
|
bool carry_bit = false;
|
||||||
|
|
||||||
spvutils::round_direction rounding[] = {
|
spvutils::round_direction rounding[] = {
|
||||||
spvutils::round_direction::kToZero,
|
spvutils::kRoundToZero,
|
||||||
spvutils::round_direction::kToNearestEven,
|
spvutils::kRoundToNearestEven,
|
||||||
spvutils::round_direction::kToPositiveInfinity,
|
spvutils::kRoundToPositiveInfinity,
|
||||||
spvutils::round_direction::kToNegativeInfinity};
|
spvutils::kRoundToNegativeInfinity};
|
||||||
|
|
||||||
// Everything fits, so everything should just be bit-shifts.
|
// Everything fits, so everything should just be bit-shifts.
|
||||||
for (spvutils::round_direction round : rounding) {
|
for (spvutils::round_direction round : rounding) {
|
||||||
@@ -852,10 +851,10 @@ std::string get_round_text(spvutils::round_direction direction) {
|
|||||||
return #round_direction
|
return #round_direction
|
||||||
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
CASE(spvutils::round_direction::kToZero);
|
CASE(spvutils::kRoundToZero);
|
||||||
CASE(spvutils::round_direction::kToPositiveInfinity);
|
CASE(spvutils::kRoundToPositiveInfinity);
|
||||||
CASE(spvutils::round_direction::kToNegativeInfinity);
|
CASE(spvutils::kRoundToNegativeInfinity);
|
||||||
CASE(spvutils::round_direction::kToNearestEven);
|
CASE(spvutils::kRoundToNearestEven);
|
||||||
}
|
}
|
||||||
#undef CASE
|
#undef CASE
|
||||||
return "";
|
return "";
|
||||||
@@ -884,35 +883,35 @@ INSTANTIATE_TEST_CASE_P(F32ToF16, HexFloatFP32To16Tests,
|
|||||||
::testing::ValuesIn(std::vector<DownCastTest>(
|
::testing::ValuesIn(std::vector<DownCastTest>(
|
||||||
{
|
{
|
||||||
// Exactly representable as half.
|
// Exactly representable as half.
|
||||||
{0.f, 0x0, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{0.f, 0x0, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{-0.f, 0x8000, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{-0.f, 0x8000, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{1.0f, 0x3C00, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{1.0f, 0x3C00, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{-1.0f, 0xBC00, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{-1.0f, 0xBC00, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
|
|
||||||
{float_fractions({0, 1, 10}) , 0x3E01, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{float_fractions({0, 1, 10}) , 0x3E01, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{-float_fractions({0, 1, 10}) , 0xBE01, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{-float_fractions({0, 1, 10}) , 0xBE01, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{static_cast<float>(ldexp(float_fractions({0, 1, 10}), 3)), 0x4A01, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{static_cast<float>(ldexp(float_fractions({0, 1, 10}), 3)), 0x4A01, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{static_cast<float>(-ldexp(float_fractions({0, 1, 10}), 3)), 0xCA01, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{static_cast<float>(-ldexp(float_fractions({0, 1, 10}), 3)), 0xCA01, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
|
|
||||||
|
|
||||||
// Underflow
|
// Underflow
|
||||||
{static_cast<float>(ldexp(1.0f, -25)), 0x0, {RD::kToZero, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{static_cast<float>(ldexp(1.0f, -25)), 0x0, {spvutils::kRoundToZero, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{static_cast<float>(ldexp(1.0f, -25)), 0x1, {RD::kToPositiveInfinity}},
|
{static_cast<float>(ldexp(1.0f, -25)), 0x1, {spvutils::kRoundToPositiveInfinity}},
|
||||||
{static_cast<float>(-ldexp(1.0f, -25)), 0x8000, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNearestEven}},
|
{static_cast<float>(-ldexp(1.0f, -25)), 0x8000, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{static_cast<float>(-ldexp(1.0f, -25)), 0x8001, {RD::kToNegativeInfinity}},
|
{static_cast<float>(-ldexp(1.0f, -25)), 0x8001, {spvutils::kRoundToNegativeInfinity}},
|
||||||
{static_cast<float>(ldexp(1.0f, -24)), 0x1, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{static_cast<float>(ldexp(1.0f, -24)), 0x1, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
|
|
||||||
// Overflow
|
// Overflow
|
||||||
{static_cast<float>(ldexp(1.0f, 16)), positive_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{static_cast<float>(ldexp(1.0f, 16)), positive_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{static_cast<float>(ldexp(1.0f, 18)), positive_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{static_cast<float>(ldexp(1.0f, 18)), positive_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{static_cast<float>(ldexp(1.3f, 16)), positive_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{static_cast<float>(ldexp(1.3f, 16)), positive_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{static_cast<float>(-ldexp(1.0f, 16)), negative_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{static_cast<float>(-ldexp(1.0f, 16)), negative_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{static_cast<float>(-ldexp(1.0f, 18)), negative_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{static_cast<float>(-ldexp(1.0f, 18)), negative_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{static_cast<float>(-ldexp(1.3f, 16)), negative_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{static_cast<float>(-ldexp(1.3f, 16)), negative_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
|
|
||||||
// Transfer of Infinities
|
// Transfer of Infinities
|
||||||
{std::numeric_limits<float>::infinity(), positive_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{std::numeric_limits<float>::infinity(), positive_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
{-std::numeric_limits<float>::infinity(), negative_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}},
|
{-std::numeric_limits<float>::infinity(), negative_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}},
|
||||||
|
|
||||||
// Nans are below because we cannot test for equality.
|
// Nans are below because we cannot test for equality.
|
||||||
})),);
|
})),);
|
||||||
@@ -929,10 +928,10 @@ TEST_P(HexFloatFP16To32Tests, WideningCasts) {
|
|||||||
HF16 f(GetParam().source_half);
|
HF16 f(GetParam().source_half);
|
||||||
|
|
||||||
spvutils::round_direction rounding[] = {
|
spvutils::round_direction rounding[] = {
|
||||||
spvutils::round_direction::kToZero,
|
spvutils::kRoundToZero,
|
||||||
spvutils::round_direction::kToNearestEven,
|
spvutils::kRoundToNearestEven,
|
||||||
spvutils::round_direction::kToPositiveInfinity,
|
spvutils::kRoundToPositiveInfinity,
|
||||||
spvutils::round_direction::kToNegativeInfinity};
|
spvutils::kRoundToNegativeInfinity};
|
||||||
|
|
||||||
// Everything fits, so everything should just be bit-shifts.
|
// Everything fits, so everything should just be bit-shifts.
|
||||||
for (spvutils::round_direction round : rounding) {
|
for (spvutils::round_direction round : rounding) {
|
||||||
@@ -972,10 +971,10 @@ TEST(HexFloatOperationTests, NanTests) {
|
|||||||
using HF = spvutils::HexFloat<spvutils::FloatProxy<float>>;
|
using HF = spvutils::HexFloat<spvutils::FloatProxy<float>>;
|
||||||
using HF16 = spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>>;
|
using HF16 = spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>>;
|
||||||
spvutils::round_direction rounding[] = {
|
spvutils::round_direction rounding[] = {
|
||||||
spvutils::round_direction::kToZero,
|
spvutils::kRoundToZero,
|
||||||
spvutils::round_direction::kToNearestEven,
|
spvutils::kRoundToNearestEven,
|
||||||
spvutils::round_direction::kToPositiveInfinity,
|
spvutils::kRoundToPositiveInfinity,
|
||||||
spvutils::round_direction::kToNegativeInfinity};
|
spvutils::kRoundToNegativeInfinity};
|
||||||
|
|
||||||
// Everything fits, so everything should just be bit-shifts.
|
// Everything fits, so everything should just be bit-shifts.
|
||||||
for (spvutils::round_direction round : rounding) {
|
for (spvutils::round_direction round : rounding) {
|
||||||
|
|||||||
@@ -1330,7 +1330,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
|||||||
|
|
||||||
const auto getMember = [&](bool flatten, TIntermTyped* node,
|
const auto getMember = [&](bool flatten, TIntermTyped* node,
|
||||||
const TVector<TVariable*>& memberVariables, int member,
|
const TVector<TVariable*>& memberVariables, int member,
|
||||||
TOperator op, const TType& memberType) {
|
TOperator op, const TType& memberType) -> TIntermTyped * {
|
||||||
TIntermTyped* subTree;
|
TIntermTyped* subTree;
|
||||||
if (flatten)
|
if (flatten)
|
||||||
subTree = intermediate.addSymbol(*memberVariables[member]);
|
subTree = intermediate.addSymbol(*memberVariables[member]);
|
||||||
@@ -3037,7 +3037,7 @@ void HlslParseContext::handleRegister(const TSourceLoc& loc, TQualifier& qualifi
|
|||||||
|
|
||||||
// space
|
// space
|
||||||
unsigned int setNumber;
|
unsigned int setNumber;
|
||||||
const auto crackSpace = [&]() {
|
const auto crackSpace = [&]() -> bool {
|
||||||
const int spaceLen = 5;
|
const int spaceLen = 5;
|
||||||
if (spaceDesc->size() < spaceLen + 1)
|
if (spaceDesc->size() < spaceLen + 1)
|
||||||
return false;
|
return false;
|
||||||
@@ -4233,7 +4233,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
|
|||||||
symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
|
symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
|
||||||
|
|
||||||
// can 'from' convert to 'to'?
|
// can 'from' convert to 'to'?
|
||||||
const auto convertible = [this](const TType& from, const TType& to) {
|
const auto convertible = [this](const TType& from, const TType& to) -> bool {
|
||||||
if (from == to)
|
if (from == to)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -4260,7 +4260,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
|
|||||||
// Is 'to2' a better conversion than 'to1'?
|
// Is 'to2' a better conversion than 'to1'?
|
||||||
// Ties should not be considered as better.
|
// Ties should not be considered as better.
|
||||||
// Assumes 'convertible' already said true.
|
// Assumes 'convertible' already said true.
|
||||||
const auto better = [](const TType& from, const TType& to1, const TType& to2) {
|
const auto better = [](const TType& from, const TType& to1, const TType& to2) -> bool {
|
||||||
// exact match is always better than mismatch
|
// exact match is always better than mismatch
|
||||||
if (from == to2)
|
if (from == to2)
|
||||||
return from != to1;
|
return from != to1;
|
||||||
@@ -4287,7 +4287,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
|
|||||||
// - 32 vs. 64 bit (or width in general)
|
// - 32 vs. 64 bit (or width in general)
|
||||||
// - bool vs. non bool
|
// - bool vs. non bool
|
||||||
// - signed vs. not signed
|
// - signed vs. not signed
|
||||||
const auto linearize = [](const TBasicType& basicType) {
|
const auto linearize = [](const TBasicType& basicType) -> int {
|
||||||
switch (basicType) {
|
switch (basicType) {
|
||||||
case EbtBool: return 1;
|
case EbtBool: return 1;
|
||||||
case EbtInt: return 10;
|
case EbtInt: return 10;
|
||||||
|
|||||||
Reference in New Issue
Block a user