Add rendering tests for all color formats

BUG=dawn:128

Change-Id: I32cab39e77847388a7736a51532a1b5c24a0fde7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/8684
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2019-07-12 07:13:41 +00:00 committed by Commit Bot service account
parent e896a0da66
commit 2d8ba5fac6
4 changed files with 197 additions and 90 deletions

View File

@ -109,6 +109,10 @@ uint16_t Float32ToFloat16(float fp32) {
}
}
bool IsFloat16NaN(uint16_t fp16) {
return (fp16 & 0x7FFF) > 0x7C00;
}
// Based on the Khronos Data Format Specification 1.2 Section 13.3 sRGB transfer functions
float SRGBToLinear(float srgb) {
// sRGB is always used in unsigned normalized formats so clamp to [0.0, 1.0]

View File

@ -51,6 +51,7 @@ destType BitCast(const sourceType& source) {
}
uint16_t Float32ToFloat16(float fp32);
bool IsFloat16NaN(uint16_t fp16);
float SRGBToLinear(float srgb);

View File

@ -71,6 +71,44 @@ class ExpectFloatWithTolerance : public detail::Expectation {
float mTolerance;
};
// An expectation for float16 buffers that can correctly compare NaNs (all NaNs are equivalent).
class ExpectFloat16 : public detail::Expectation {
public:
ExpectFloat16(std::vector<uint16_t> expected) : mExpected(std::move(expected)) {
}
testing::AssertionResult Check(const void* data, size_t size) override {
ASSERT(size == sizeof(uint16_t) * mExpected.size());
const uint16_t* actual = static_cast<const uint16_t*>(data);
for (size_t i = 0; i < mExpected.size(); ++i) {
uint16_t expectedValue = mExpected[i];
uint16_t actualValue = actual[i];
if (!Floats16Match(expectedValue, actualValue)) {
testing::AssertionResult result = testing::AssertionFailure()
<< "Expected data[" << i << "] to be "
<< expectedValue << ", actual " << actualValue
<< std::endl;
return result;
}
}
return testing::AssertionSuccess();
}
private:
bool Floats16Match(float expected, float actual) {
if (IsFloat16NaN(expected)) {
return IsFloat16NaN(actual);
}
return expected == actual;
}
std::vector<uint16_t> mExpected;
};
class TextureFormatTest : public DawnTest {
protected:
void SetUp() {
@ -97,9 +135,9 @@ class TextureFormatTest : public DawnTest {
uint32_t componentCount;
};
// Returns a texture format that can be used to contain the interpreted value of the format in
// formatInfo.
dawn::TextureFormat GetComponentFormat(FormatTestInfo formatInfo) {
// Returns a reprensentation of a format that can be used to contain the "uncompressed" values
// of the format. That the equivalent format with all channels 32bit-sized.
FormatTestInfo GetUncompressedFormatInfo(FormatTestInfo formatInfo) {
std::array<dawn::TextureFormat, 4> floatFormats = {
dawn::TextureFormat::R32Float,
dawn::TextureFormat::RG32Float,
@ -118,24 +156,32 @@ class TextureFormatTest : public DawnTest {
dawn::TextureFormat::RGBA32Uint,
dawn::TextureFormat::RGBA32Uint,
};
std::array<uint32_t, 4> componentCounts = {1, 2, 4, 4};
ASSERT(formatInfo.componentCount > 0 && formatInfo.componentCount <= 4);
dawn::TextureFormat format;
switch (formatInfo.type) {
case Float:
return floatFormats[formatInfo.componentCount - 1];
format = floatFormats[formatInfo.componentCount - 1];
break;
case Sint:
return sintFormats[formatInfo.componentCount - 1];
format = sintFormats[formatInfo.componentCount - 1];
break;
case Uint:
return uintFormats[formatInfo.componentCount - 1];
format = uintFormats[formatInfo.componentCount - 1];
break;
default:
UNREACHABLE();
return dawn::TextureFormat::R32Float;
}
uint32_t componentCount = componentCounts[formatInfo.componentCount - 1];
return {format, 4 * componentCount, formatInfo.type, componentCount};
}
// Return a pipeline that can be used in a full-texture draw to sample from the texture in the
// bindgroup and output its decompressed values to the render target.
dawn::RenderPipeline CreateSamplePipeline(FormatTestInfo formatInfo) {
dawn::RenderPipeline CreateSamplePipeline(FormatTestInfo sampleFormatInfo,
FormatTestInfo renderFormatInfo) {
utils::ComboRenderPipelineDescriptor desc(device);
dawn::ShaderModule vsModule =
@ -152,7 +198,7 @@ class TextureFormatTest : public DawnTest {
// Compute the prefix needed for GLSL types that handle our texture's data.
const char* prefix = nullptr;
switch (formatInfo.type) {
switch (sampleFormatInfo.type) {
case Float:
prefix = "";
break;
@ -184,66 +230,63 @@ class TextureFormatTest : public DawnTest {
desc.cVertexStage.module = vsModule;
desc.cFragmentStage.module = fsModule;
desc.layout = utils::MakeBasicPipelineLayout(device, &mSampleBGL);
desc.cColorStates[0]->format = GetComponentFormat(formatInfo);
desc.cColorStates[0]->format = renderFormatInfo.format;
return device.CreateRenderPipeline(&desc);
}
// The sampling test uploads the textureData in a texture with the formatInfo.format format and
// the samples from it, then checks that the sampled values correspond to expectedRenderData.
void DoSampleTest(FormatTestInfo formatInfo,
const void* textureData,
size_t textureDataSize,
// The sampling test uploads the sample data in a texture with the sampleFormatInfo.format.
// It then samples from it and renders the results in a texture with the
// renderFormatInfo.format format. Finally it checks that the data rendered matches
// expectedRenderData, using the cutom expectation if present.
void DoSampleTest(FormatTestInfo sampleFormatInfo,
const void* sampleData,
size_t sampleDataSize,
FormatTestInfo renderFormatInfo,
const void* expectedRenderData,
size_t expectedRenderDataSize,
float floatTolerance) {
detail::Expectation* customExpectation) {
// The input data should contain an exact number of texels
ASSERT(textureDataSize % formatInfo.texelByteSize == 0);
uint32_t width = textureDataSize / formatInfo.texelByteSize;
ASSERT(sampleDataSize % sampleFormatInfo.texelByteSize == 0);
uint32_t width = sampleDataSize / sampleFormatInfo.texelByteSize;
// The input data must be a multiple of 4 byte in length for setSubData
ASSERT(textureDataSize % 4 == 0);
ASSERT(sampleDataSize % 4 == 0);
ASSERT(expectedRenderDataSize % 4 == 0);
// Create the texture we will sample from
dawn::TextureDescriptor textureDesc;
textureDesc.usage = dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::Sampled;
textureDesc.dimension = dawn::TextureDimension::e2D;
textureDesc.size = {width, 1, 1};
textureDesc.arrayLayerCount = 1;
textureDesc.format = formatInfo.format;
textureDesc.mipLevelCount = 1;
textureDesc.sampleCount = 1;
dawn::TextureDescriptor sampleTextureDesc;
sampleTextureDesc.usage = dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::Sampled;
sampleTextureDesc.size = {width, 1, 1};
sampleTextureDesc.format = sampleFormatInfo.format;
dawn::Texture sampleTexture = device.CreateTexture(&sampleTextureDesc);
dawn::Texture texture = device.CreateTexture(&textureDesc);
dawn::Buffer uploadBuffer = utils::CreateBufferFromData(
device, textureData, textureDataSize, dawn::BufferUsageBit::CopySrc);
dawn::Buffer uploadBuffer = utils::CreateBufferFromData(device, sampleData, sampleDataSize,
dawn::BufferUsageBit::CopySrc);
// Create the texture that we will render results to
ASSERT(expectedRenderDataSize == width * renderFormatInfo.texelByteSize);
dawn::TextureDescriptor renderTargetDesc;
renderTargetDesc.usage =
dawn::TextureUsageBit::CopySrc | dawn::TextureUsageBit::OutputAttachment;
renderTargetDesc.dimension = dawn::TextureDimension::e2D;
renderTargetDesc.size = {width, 1, 1};
renderTargetDesc.arrayLayerCount = 1;
renderTargetDesc.format = GetComponentFormat(formatInfo);
renderTargetDesc.mipLevelCount = 1;
renderTargetDesc.sampleCount = 1;
renderTargetDesc.format = renderFormatInfo.format;
dawn::Texture renderTarget = device.CreateTexture(&renderTargetDesc);
// Create the readback buffer for the data in renderTarget
dawn::BufferDescriptor readbackBufferDesc;
readbackBufferDesc.usage = dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::CopySrc;
readbackBufferDesc.size = 4 * width * formatInfo.componentCount;
readbackBufferDesc.size = 4 * width * sampleFormatInfo.componentCount;
dawn::Buffer readbackBuffer = device.CreateBuffer(&readbackBufferDesc);
// Prepare objects needed to sample from texture in the renderpass
dawn::RenderPipeline pipeline = CreateSamplePipeline(formatInfo);
dawn::RenderPipeline pipeline = CreateSamplePipeline(sampleFormatInfo, renderFormatInfo);
dawn::SamplerDescriptor samplerDesc = utils::GetDefaultSamplerDescriptor();
dawn::Sampler sampler = device.CreateSampler(&samplerDesc);
dawn::BindGroup bindGroup = utils::MakeBindGroup(
device, mSampleBGL, {{0, sampler}, {1, texture.CreateDefaultView()}});
device, mSampleBGL, {{0, sampler}, {1, sampleTexture.CreateDefaultView()}});
// Encode commands for the test that fill texture, sample it to render to renderTarget then
// copy renderTarget in a buffer so we can read it easily.
@ -252,7 +295,7 @@ class TextureFormatTest : public DawnTest {
{
dawn::BufferCopyView bufferView = utils::CreateBufferCopyView(uploadBuffer, 0, 256, 0);
dawn::TextureCopyView textureView =
utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0});
utils::CreateTextureCopyView(sampleTexture, 0, 0, {0, 0, 0});
dawn::Extent3D extent{width, 1, 1};
encoder.CopyBufferToTexture(&bufferView, &textureView, &extent);
}
@ -278,12 +321,9 @@ class TextureFormatTest : public DawnTest {
// For floats use a special expectation that understands how to compare NaNs and support a
// tolerance.
if (formatInfo.type == Float) {
const float* expectedFloats = static_cast<const float*>(expectedRenderData);
std::vector<float> expectedVector(
expectedFloats, expectedFloats + expectedRenderDataSize / sizeof(float));
if (customExpectation != nullptr) {
AddBufferExpectation(__FILE__, __LINE__, readbackBuffer, 0, expectedRenderDataSize,
new ExpectFloatWithTolerance(expectedVector, floatTolerance));
customExpectation);
} else {
EXPECT_BUFFER_U32_RANGE_EQ(static_cast<const uint32_t*>(expectedRenderData),
readbackBuffer, 0,
@ -291,14 +331,38 @@ class TextureFormatTest : public DawnTest {
}
}
// Helper functions used to run tests that convert the typeful test objects to typeless void*
template <typename TextureData, typename RenderData>
void DoSampleTest(FormatTestInfo formatInfo,
const std::vector<TextureData>& textureData,
const std::vector<RenderData>& expectedRenderData,
float floatTolerance = 0.0f) {
void DoFormatSamplingTest(FormatTestInfo formatInfo,
const std::vector<TextureData>& textureData,
const std::vector<RenderData>& expectedRenderData,
detail::Expectation* customExpectation = nullptr) {
FormatTestInfo renderFormatInfo = GetUncompressedFormatInfo(formatInfo);
DoSampleTest(formatInfo, textureData.data(), textureData.size() * sizeof(TextureData),
expectedRenderData.data(), expectedRenderData.size() * sizeof(RenderData),
floatTolerance);
renderFormatInfo, expectedRenderData.data(),
expectedRenderData.size() * sizeof(RenderData), customExpectation);
}
template <typename TextureData>
void DoFloatFormatSamplingTest(FormatTestInfo formatInfo,
const std::vector<TextureData>& textureData,
const std::vector<float>& expectedRenderData,
float floatTolerance = 0.0f) {
// Use a special expectation that understands how to compare NaNs and supports a tolerance.
DoFormatSamplingTest(formatInfo, textureData, expectedRenderData,
new ExpectFloatWithTolerance(expectedRenderData, floatTolerance));
}
template <typename TextureData, typename RenderData>
void DoFormatRenderingTest(FormatTestInfo formatInfo,
const std::vector<TextureData>& textureData,
const std::vector<RenderData>& expectedRenderData,
detail::Expectation* customExpectation = nullptr) {
FormatTestInfo sampleFormatInfo = GetUncompressedFormatInfo(formatInfo);
DoSampleTest(sampleFormatInfo, textureData.data(), textureData.size() * sizeof(TextureData),
formatInfo, expectedRenderData.data(),
expectedRenderData.size() * sizeof(RenderData), customExpectation);
}
// Below are helper functions for types that are very similar to one another so the logic is
@ -312,9 +376,10 @@ class TextureFormatTest : public DawnTest {
T maxValue = std::numeric_limits<T>::max();
std::vector<T> textureData = {0, 1, maxValue, maxValue};
std::vector<float> expectedData = {0.0f, 1.0f / maxValue, 1.0f, 1.0f};
std::vector<float> uncompressedData = {0.0f, 1.0f / maxValue, 1.0f, 1.0f};
DoSampleTest(formatInfo, textureData, expectedData);
DoFormatSamplingTest(formatInfo, textureData, uncompressedData);
DoFormatRenderingTest(formatInfo, uncompressedData, textureData);
}
template <typename T>
@ -326,9 +391,14 @@ class TextureFormatTest : public DawnTest {
T maxValue = std::numeric_limits<T>::max();
T minValue = std::numeric_limits<T>::min();
std::vector<T> textureData = {0, 1, maxValue, minValue};
std::vector<float> expectedData = {0.0f, 1.0f / maxValue, 1.0f, -1.0f};
std::vector<float> uncompressedData = {0.0f, 1.0f / maxValue, 1.0f, -1.0f};
DoSampleTest(formatInfo, textureData, expectedData, 0.0001f / maxValue);
DoFloatFormatSamplingTest(formatInfo, textureData, uncompressedData, 0.0001f / maxValue);
// It is not possible to render minValue because -1.0f is the minimum and corresponds to
// -maxValue (minValue is - maxValue -1)
textureData[3] = -maxValue;
DoFormatRenderingTest(formatInfo, uncompressedData, textureData);
}
template <typename T>
@ -339,9 +409,10 @@ class TextureFormatTest : public DawnTest {
T maxValue = std::numeric_limits<T>::max();
std::vector<T> textureData = {0, 1, maxValue, maxValue};
std::vector<uint32_t> expectedData = {0, 1, maxValue, maxValue};
std::vector<uint32_t> uncompressedData = {0, 1, maxValue, maxValue};
DoSampleTest(formatInfo, textureData, expectedData);
DoFormatSamplingTest(formatInfo, textureData, uncompressedData);
DoFormatRenderingTest(formatInfo, uncompressedData, textureData);
}
template <typename T>
@ -353,9 +424,10 @@ class TextureFormatTest : public DawnTest {
T maxValue = std::numeric_limits<T>::max();
T minValue = std::numeric_limits<T>::min();
std::vector<T> textureData = {0, 1, maxValue, minValue};
std::vector<int32_t> expectedData = {0, 1, maxValue, minValue};
std::vector<int32_t> uncompressedData = {0, 1, maxValue, minValue};
DoSampleTest(formatInfo, textureData, expectedData);
DoFormatSamplingTest(formatInfo, textureData, uncompressedData);
DoFormatRenderingTest(formatInfo, uncompressedData, textureData);
}
void DoFloat32Test(FormatTestInfo formatInfo) {
@ -365,21 +437,26 @@ class TextureFormatTest : public DawnTest {
std::vector<float> textureData = {+0.0f, -0.0f, 1.0f, 1.0e-29f,
1.0e29, NAN, INFINITY, -INFINITY};
DoSampleTest(formatInfo, textureData, textureData);
DoFloatFormatSamplingTest(formatInfo, textureData, textureData);
DoFormatRenderingTest(formatInfo, textureData, textureData);
}
void DoFloat16Test(FormatTestInfo formatInfo) {
ASSERT(sizeof(int16_t) * formatInfo.componentCount == formatInfo.texelByteSize);
ASSERT(formatInfo.type == Float);
std::vector<float> expectedData = {+0.0f, -0.0f, 1.0f, 1.0e-4f,
1.0e4f, NAN, INFINITY, -INFINITY};
std::vector<float> uncompressedData = {+0.0f, -0.0f, 1.0f, 1.01e-4f,
1.0e4f, NAN, INFINITY, -INFINITY};
std::vector<uint16_t> textureData;
for (float value : expectedData) {
for (float value : uncompressedData) {
textureData.push_back(Float32ToFloat16(value));
}
DoSampleTest(formatInfo, textureData, expectedData, 1.0e-5);
DoFloatFormatSamplingTest(formatInfo, textureData, uncompressedData, 1.0e-5);
// Use a special expectation that knows that all Float16 NaNs are equivalent.
DoFormatRenderingTest(formatInfo, uncompressedData, textureData,
new ExpectFloat16(textureData));
}
private:
@ -420,8 +497,11 @@ TEST_P(TextureFormatTest, RGBA16Unorm) {
TEST_P(TextureFormatTest, BGRA8Unorm) {
uint8_t maxValue = std::numeric_limits<uint8_t>::max();
std::vector<uint8_t> textureData = {maxValue, 1, 0, maxValue};
std::vector<float> expectedData = {0.0f, 1.0f / maxValue, 1.0f, 1.0f};
DoSampleTest({dawn::TextureFormat::BGRA8Unorm, 4, Float, 4}, textureData, expectedData);
std::vector<float> uncompressedData = {0.0f, 1.0f / maxValue, 1.0f, 1.0f};
DoFormatSamplingTest({dawn::TextureFormat::BGRA8Unorm, 4, Float, 4}, textureData,
uncompressedData);
DoFormatRenderingTest({dawn::TextureFormat::BGRA8Unorm, 4, Float, 4}, uncompressedData,
textureData);
}
// Test the R8Snorm format
@ -579,36 +659,40 @@ TEST_P(TextureFormatTest, RGBA8UnormSrgb) {
uint8_t maxValue = std::numeric_limits<uint8_t>::max();
std::vector<uint8_t> textureData = {0, 1, maxValue, 64, 35, 68, 152, 168};
std::vector<float> expectedData;
std::vector<float> uncompressedData;
for (size_t i = 0; i < textureData.size(); i += 4) {
expectedData.push_back(SRGBToLinear(textureData[i + 0] / float(maxValue)));
expectedData.push_back(SRGBToLinear(textureData[i + 1] / float(maxValue)));
expectedData.push_back(SRGBToLinear(textureData[i + 2] / float(maxValue)));
uncompressedData.push_back(SRGBToLinear(textureData[i + 0] / float(maxValue)));
uncompressedData.push_back(SRGBToLinear(textureData[i + 1] / float(maxValue)));
uncompressedData.push_back(SRGBToLinear(textureData[i + 2] / float(maxValue)));
// Alpha is linear for sRGB formats
expectedData.push_back(textureData[i + 3] / float(maxValue));
uncompressedData.push_back(textureData[i + 3] / float(maxValue));
}
DoSampleTest({dawn::TextureFormat::RGBA8UnormSrgb, 4, Float, 4}, textureData, expectedData,
1.0e-3);
DoFloatFormatSamplingTest({dawn::TextureFormat::RGBA8UnormSrgb, 4, Float, 4}, textureData,
uncompressedData, 1.0e-3);
DoFormatRenderingTest({dawn::TextureFormat::RGBA8UnormSrgb, 4, Float, 4}, uncompressedData,
textureData);
}
// Test the BGRA8Unorm format
// Test the BGRA8UnormSrgb format
TEST_P(TextureFormatTest, BGRA8UnormSrgb) {
uint8_t maxValue = std::numeric_limits<uint8_t>::max();
std::vector<uint8_t> textureData = {0, 1, maxValue, 64, 35, 68, 152, 168};
std::vector<float> expectedData;
std::vector<float> uncompressedData;
for (size_t i = 0; i < textureData.size(); i += 4) {
// Note that R and B are swapped
expectedData.push_back(SRGBToLinear(textureData[i + 2] / float(maxValue)));
expectedData.push_back(SRGBToLinear(textureData[i + 1] / float(maxValue)));
expectedData.push_back(SRGBToLinear(textureData[i + 0] / float(maxValue)));
uncompressedData.push_back(SRGBToLinear(textureData[i + 2] / float(maxValue)));
uncompressedData.push_back(SRGBToLinear(textureData[i + 1] / float(maxValue)));
uncompressedData.push_back(SRGBToLinear(textureData[i + 0] / float(maxValue)));
// Alpha is linear for sRGB formats
expectedData.push_back(textureData[i + 3] / float(maxValue));
uncompressedData.push_back(textureData[i + 3] / float(maxValue));
}
DoSampleTest({dawn::TextureFormat::BGRA8UnormSrgb, 4, Float, 4}, textureData, expectedData,
1.0e-3);
DoFloatFormatSamplingTest({dawn::TextureFormat::BGRA8UnormSrgb, 4, Float, 4}, textureData,
uncompressedData, 1.0e-3);
DoFormatRenderingTest({dawn::TextureFormat::BGRA8UnormSrgb, 4, Float, 4}, uncompressedData,
textureData);
}
// Test the RGB10A2Unorm format
@ -622,18 +706,20 @@ TEST_P(TextureFormatTest, RGB10A2Unorm) {
};
std::vector<uint32_t> textureData = {MakeRGB10A2(0, 0, 0, 0), MakeRGB10A2(1023, 1023, 1023, 1),
MakeRGB10A2(243, 578, 765, 2), MakeRGB10A2(0, 0, 0, 3)};
MakeRGB10A2(243, 576, 765, 2), MakeRGB10A2(0, 0, 0, 3)};
// clang-format off
std::vector<float> expectedData = {
0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1 / 3.0f,
std::vector<float> uncompressedData = {
0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1 / 3.0f,
243 / 1023.0f, 576 / 1023.0f, 765 / 1023.0f, 2 / 3.0f,
0.0f, 0.0f, 0.0f, 1.0f
0.0f, 0.0f, 0.0f, 1.0f
};
// clang-format on
DoSampleTest({dawn::TextureFormat::RGB10A2Unorm, 4, Float, 4}, textureData, expectedData,
2.0e-3);
DoFloatFormatSamplingTest({dawn::TextureFormat::RGB10A2Unorm, 4, Float, 4}, textureData,
uncompressedData, 1.0e-5);
DoFormatRenderingTest({dawn::TextureFormat::RGB10A2Unorm, 4, Float, 4}, uncompressedData,
textureData);
}
// Test the RG11B10Float format
@ -667,7 +753,7 @@ TEST_P(TextureFormatTest, RG11B10Float) {
// This is one of the only 3-channel formats, so we don't have specific testing for them. Alpha
// should slways be sampled as 1
// clang-format off
std::vector<float> expectedData = {
std::vector<float> uncompressedData = {
0.0f, INFINITY, NAN, 1.0f,
INFINITY, NAN, 1.0f, 1.0f,
NAN, 1.0f, 0.0f, 1.0f,
@ -675,7 +761,9 @@ TEST_P(TextureFormatTest, RG11B10Float) {
};
// clang-format on
DoSampleTest({dawn::TextureFormat::RG11B10Float, 4, Float, 4}, textureData, expectedData);
DoFloatFormatSamplingTest({dawn::TextureFormat::RG11B10Float, 4, Float, 4}, textureData,
uncompressedData);
// This format is not renderable.
}
// TODO(cwallez@chromium.org): Add tests for depth-stencil formats when we know if they are copyable

View File

@ -151,6 +151,20 @@ TEST(Math, Float32ToFloat16) {
ASSERT_EQ(Float32ToFloat16(1.0f), 0x3C00);
}
// Tests for IsFloat16NaN
TEST(Math, IsFloat16NaN) {
ASSERT_FALSE(IsFloat16NaN(0u));
ASSERT_FALSE(IsFloat16NaN(0u));
ASSERT_FALSE(IsFloat16NaN(Float32ToFloat16(1.0f)));
ASSERT_FALSE(IsFloat16NaN(Float32ToFloat16(INFINITY)));
ASSERT_FALSE(IsFloat16NaN(Float32ToFloat16(-INFINITY)));
ASSERT_TRUE(IsFloat16NaN(Float32ToFloat16(INFINITY) + 1));
ASSERT_TRUE(IsFloat16NaN(Float32ToFloat16(-INFINITY) + 1));
ASSERT_TRUE(IsFloat16NaN(0x7FFF));
ASSERT_TRUE(IsFloat16NaN(0xFFFF));
}
// Tests for SRGBToLinear
TEST(Math, SRGBToLinear) {
ASSERT_EQ(SRGBToLinear(0.0f), 0.0f);