Commit 3e251337 by Jamie Madill Committed by Commit Bot

Removed SizedFloat helper class from upload tests.

This helper was redundant with the image utils library. Switch the test to use the existing methods. Doesn't affect test correctness. This removes more 'configless' tests from angle_end2end_tests. Bug: angleproject:3393 Change-Id: I49cfbd95c3713b2b4b25c4716a7a279d84ddf994 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1591426Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 926f1caa
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
// //
#include "common/mathutil.h" #include "common/mathutil.h"
#include "image_util/copyimage.h"
#include "test_utils/ANGLETest.h" #include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h" #include "test_utils/gl_raii.h"
...@@ -104,183 +105,8 @@ constexpr uint32_t EncodeNormUint(const float val) ...@@ -104,183 +105,8 @@ constexpr uint32_t EncodeNormUint(const float val)
return static_cast<uint32_t>(val * (UINT32_MAX >> (32 - bits)) + 0.5); // round-half-up return static_cast<uint32_t>(val * (UINT32_MAX >> (32 - bits)) + 0.5); // round-half-up
} }
template <const int signBit, const int eBits, const int mBits>
struct SizedFloat
{
static constexpr int kSignBit = signBit;
static constexpr int kEBits = eBits;
static constexpr int kMBits = mBits;
static constexpr uint32_t Assemble(const uint32_t sVal,
const uint32_t eVal,
const uint32_t mVal)
{
return (signBit ? (sVal << (eBits + mBits)) : 0) | (eVal << mBits) | mVal;
}
static uint32_t Encode(const float signedV)
{
const float v = signBit ? fabsf(signedV) : std::max(0.0f, signedV);
const int eBias = (1 << (eBits - 1)) - 1;
const int eValMax = (1 << eBits) - 1;
const float eApprox = log2f(v);
const auto eActual = static_cast<int>(floorf(eApprox));
int eVal = eBias + eActual;
uint32_t mVal = 0;
if (v != v)
{ // NaN
eVal = eValMax;
mVal = 1;
}
else if (eVal < 0)
{ // underflow to zero
eVal = 0;
mVal = 0;
}
else if (eVal >= eValMax)
{ // overfloat to Inf
eVal = eValMax;
mVal = 0;
}
else
{
float mFloat = 0.0;
if (eVal == 0)
{ // denormal
mFloat = v * powf(2, 1 - eBias);
}
else
{ // standard range
mFloat = v * powf(2, -static_cast<float>(eActual)) - 1.0f;
}
mVal = static_cast<uint32_t>(mFloat * (1 << mBits) + 0.5);
}
const auto sVal = static_cast<uint32_t>(v < 0.0f);
return Assemble(sVal, eVal, mVal);
}
static constexpr float Decode(const uint32_t sVal, const uint32_t eVal, const uint32_t mVal)
{
constexpr int eBias = (1 << (kEBits - 1)) - 1;
constexpr int mDiv = 1 << kMBits;
float ret = powf(-1.0f, static_cast<float>(sVal)) *
powf(2.0f, static_cast<float>(int(eVal) - eBias)) * (1.0f + float(mVal) / mDiv);
return ret;
}
};
using Float16 = SizedFloat<1, 5, 10>;
using UFloat11 = SizedFloat<0, 5, 6>;
using UFloat10 = SizedFloat<0, 5, 5>;
struct RGB9_E5 final
{
// GLES 3.0.5 p129
static constexpr int N = 9; // number of mantissa bits per component
static constexpr int B = 15; // exponent bias
static uint32_t Encode(const float red, const float green, const float blue)
{
const auto floori = [](const float x) { return static_cast<int>(floor(x)); };
// GLES 3.0.5 p129
constexpr int eMax = 31; // max allowed biased exponent value
const float twoToN = powf(2.0f, static_cast<float>(N));
const float sharedExpMax = (twoToN - 1.0f) / twoToN * powf(2.0f, eMax - B);
const auto fnClampColor = [&](const float color) {
return std::max(0.0f, std::min(color, sharedExpMax));
};
const float redC = fnClampColor(red);
const float greenC = fnClampColor(green);
const float blueC = fnClampColor(blue);
const float maxC = std::max({redC, greenC, blueC});
const int expP = std::max(-B - 1, floori(log2f(maxC))) + 1 + B;
const auto fnColorS = [&](const float colorC, const float exp) {
return floori(colorC / powf(2, exp - B - N) + 0.5f);
};
const int maxS = fnColorS(maxC, static_cast<float>(expP));
const int expS = expP + ((maxS == (1 << N)) ? 1 : 0);
const int redS = fnColorS(redC, static_cast<float>(expS));
const int greenS = fnColorS(greenC, static_cast<float>(expS));
const int blueS = fnColorS(blueC, static_cast<float>(expS));
// Pack as u32 EGBR.
uint32_t ret = expS & 0x1f;
ret <<= 9;
ret |= blueS & 0x1ff;
ret <<= 9;
ret |= greenS & 0x1ff;
ret <<= 9;
ret |= redS & 0x1ff;
return ret;
}
static void Decode(uint32_t packed,
float *const out_red,
float *const out_green,
float *const out_blue)
{
const auto redS = packed & 0x1ff;
packed >>= 9;
const auto greenS = packed & 0x1ff;
packed >>= 9;
const auto blueS = packed & 0x1ff;
packed >>= 9;
const auto expS = packed & 0x1f;
// These are *not* IEEE-like UFloat14s.
// GLES 3.0.5 p165:
// red = redS*pow(2,expS-B-N)
const auto fnToFloat = [&](const uint32_t x) {
return x * powf(2.0f, static_cast<float>(int(expS) - B - N));
};
*out_red = fnToFloat(redS);
*out_green = fnToFloat(greenS);
*out_blue = fnToFloat(blueS);
}
};
} // anonymous namespace } // anonymous namespace
// Test our encoding code to ensure we get the values out that we expect.
// We could alternatively hardcode our inputs for these couple cases, but it's nice to do this
// programatically, since it should make it easier to write any further tests without having to
// re-encode by hand.
TEST(TextureUploadFormatTestInternals, Float16Encoding)
{
EXPECT_EQ(Float16::Decode(0, 0x0f, 0), 1.0f);
EXPECT_EQ(Float16::Decode(0, 0x0f - 1, 0), 0.5f);
EXPECT_EQ(Float16::Assemble(0, 0x0f, 0), Float16::Encode(1.0));
EXPECT_EQ(Float16::Assemble(0, 0x0f - 1, 0), Float16::Encode(1.0 / 2));
EXPECT_EQ(Float16::Assemble(0, 0x0f - 3, 0), Float16::Encode(1.0 / 8));
EXPECT_EQ(Float16::Assemble(0, 0x0f - 2, 0), Float16::Encode(2.0 / 8));
EXPECT_EQ(Float16::Assemble(0, 0x0f - 2, 1 << (Float16::kMBits - 1)), Float16::Encode(3.0 / 8));
EXPECT_EQ(Float16::Assemble(0, 0x0f - 1, 1 << (Float16::kMBits - 2)), Float16::Encode(5.0 / 8));
}
// Ensure our RGB9_E5 encoding is reasonable, at least for our testcase.
TEST(TextureUploadFormatTestInternals, RGB9E5Encoding)
{
const auto fnTest = [](const float refR, const float refG, const float refB) {
const auto packed = RGB9_E5::Encode(refR, refG, refB);
float testR, testG, testB;
RGB9_E5::Decode(packed, &testR, &testG, &testB);
EXPECT_EQ(testR, refR);
EXPECT_EQ(testG, refG);
EXPECT_EQ(testB, refB);
};
fnTest(0.125f, 0.250f, 0.625f);
}
namespace namespace
{ {
...@@ -298,6 +124,17 @@ std::string EnumStr(const GLenum v) ...@@ -298,6 +124,17 @@ std::string EnumStr(const GLenum v)
return ret.str(); return ret.str();
} }
template <typename ColorT, typename DestT>
void EncodeThenZeroAndCopy(DestT &dest, const float srcVals[4])
{
ColorF srcValsF(srcVals[0], srcVals[1], srcVals[2], srcVals[3]);
ColorT encoded;
ColorT::writeColor(&encoded, &srcValsF);
dest.fill(0);
memcpy(dest.data(), &encoded, sizeof(ColorT));
}
} // anonymous namespace } // anonymous namespace
// Upload (1,2,5,3) to integer formats, and (1,2,5,3)/8.0 to float formats. // Upload (1,2,5,3) to integer formats, and (1,2,5,3)/8.0 to float formats.
...@@ -694,11 +531,7 @@ TEST_P(TextureUploadFormatTest, All) ...@@ -694,11 +531,7 @@ TEST_P(TextureUploadFormatTest, All)
// RGBA+HALF_FLOAT // RGBA+HALF_FLOAT
{ {
const uint16_t src[] = {static_cast<uint16_t>(Float16::Encode(srcVals[0])), EncodeThenZeroAndCopy<R16G16B16A16F>(srcBuffer, srcVals);
static_cast<uint16_t>(Float16::Encode(srcVals[1])),
static_cast<uint16_t>(Float16::Encode(srcVals[2])),
static_cast<uint16_t>(Float16::Encode(srcVals[3]))};
ZeroAndCopy(srcBuffer, src);
fnTest({GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, {1, 1, 1, 1}); fnTest({GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, {1, 1, 1, 1});
...@@ -738,18 +571,14 @@ TEST_P(TextureUploadFormatTest, All) ...@@ -738,18 +571,14 @@ TEST_P(TextureUploadFormatTest, All)
// UNSIGNED_INT_10F_11F_11F_REV // UNSIGNED_INT_10F_11F_11F_REV
{ {
const uint32_t src[] = {(UFloat11::Encode(srcVals[0]) << 0) | EncodeThenZeroAndCopy<R11G11B10F>(srcBuffer, srcVals);
(UFloat11::Encode(srcVals[1]) << 11) |
(UFloat10::Encode(srcVals[2]) << 22)};
ZeroAndCopy(srcBuffer, src);
fnTest({GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}, {1, 1, 1, 0}); fnTest({GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}, {1, 1, 1, 0});
} }
// UNSIGNED_INT_5_9_9_9_REV // UNSIGNED_INT_5_9_9_9_REV
{ {
const uint32_t src[] = {RGB9_E5::Encode(srcVals[0], srcVals[1], srcVals[2])}; EncodeThenZeroAndCopy<R9G9B9E5>(srcBuffer, srcVals);
ZeroAndCopy(srcBuffer, src);
fnTest({GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, {1, 1, 1, 0}); fnTest({GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, {1, 1, 1, 0});
} }
......
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