end2end: VertexFormatTest: fold bit representation of -0.0 to 0
This is necessary because of how we compute ULP in a cheap way
by looking only at the u32 bits.
Remove the test suppressions for Arm GPUs.
I suspect this also fixes the tests for other GPUs.
Bug: dawn:1566
Change-Id: I36018209cf3254acfa64771b1e40bf498bd3375a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/147243
Reviewed-by: Brandon Jones <bajones@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: David Neto <dneto@google.com>
diff --git a/src/dawn/tests/end2end/VertexFormatTests.cpp b/src/dawn/tests/end2end/VertexFormatTests.cpp
index a62c38f..f9a419d 100644
--- a/src/dawn/tests/end2end/VertexFormatTests.cpp
+++ b/src/dawn/tests/end2end/VertexFormatTests.cpp
@@ -242,6 +242,22 @@
vs << " @builtin(vertex_index) VertexIndex : u32,\n";
vs << "}\n";
+ // These functions map a 32-bit scalar value to its bits in u32, except
+ // that the negative zero floating point value is remapped to u32(0),
+ // which is also the bit representation for +0.0.
+ // This is necessary because of the simple way we compute ULP.
+ // Negative zero *equals* zero, so treat it as having the same bit
+ // representation.
+ vs << R"(
+ fn rectify_u32(a: u32) -> u32 { return a; }
+ fn rectify_i32(a: i32) -> u32 { return bitcast<u32>(a); }
+ fn rectify_f32(a: f32) -> u32 {
+ const negative_zero_bits = 1u << 31u;
+ let b = bitcast<u32>(a);
+ return select(b, 0u, b == negative_zero_bits);
+ }
+ )";
+
// Because x86 CPU using "extended
// precision"(https://en.wikipedia.org/wiki/Extended_precision) during float
// math(https://developer.nvidia.com/sites/default/files/akamai/cuda/files/NVIDIA-CUDA-Floating-Point.pdf),
@@ -310,6 +326,8 @@
// Because Vulkan and D3D12 handle -0.0f through bitcast have different
// result (Vulkan take -0.0f as -0.0 but D3D12 take -0.0f as 0), add workaround
// for -0.0f.
+ // TODO(dawn:1566) Since rectify_32 will be used, we might
+ // not need this.
if (static_cast<uint16_t>(expectedData[i * componentCount + j]) ==
kNegativeZeroInHalf) {
vs << "-0.0);\n";
@@ -342,15 +360,13 @@
vs << " success = success && (isNaNCustom(" << expectedVal << ") == isNaNCustom("
<< testVal << "));\n";
vs << " if (!isNaNCustom(" << expectedVal << ")) {\n";
- // Fold -0.0 into 0.0.
- vs << " if (" << testVal << " == 0) { " << testVal << " = 0; }\n";
- vs << " if (" << expectedVal << " == 0) { " << expectedVal << " = 0; }\n";
// TODO(shaobo.yan@intel.com) : a difference of 8 ULPs is allowed in this test
// because it is required on MacbookPro 11.5,AMD Radeon HD 8870M(on macOS 10.13.6),
// but that it might be possible to tighten.
- vs << " let testValFloatToUint : u32 = bitcast<u32>(" << testVal << ");\n";
- vs << " let expectedValFloatToUint : u32 = bitcast<u32>(" << expectedVal
- << ");\n";
+ vs << " let testValFloatToUint : u32 = rectify_" << expectedDataType << "("
+ << testVal << ");\n";
+ vs << " let expectedValFloatToUint : u32 = rectify_" << expectedDataType
+ << "(" << expectedVal << ");\n";
vs << " success = success && max(testValFloatToUint, "
"expectedValFloatToUint)";
vs << " - min(testValFloatToUint, expectedValFloatToUint) < 8u;\n";
@@ -705,9 +721,8 @@
TEST_P(VertexFormatTest, Float16x2) {
// Fails on NVIDIA's Vulkan drivers on CQ but passes locally.
+ // TODO(dawn:1566) Might pass when using rectify_f32?
DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsNvidia());
- // TODO(dawn:1566) Fails on Arm-based Android devices, when using -0.0.
- DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());
std::vector<uint16_t> vertexData =
Float32ToFloat16(std::vector<float>({14.8f, -0.0f, 22.5f, 1.3f, +0.0f, -24.8f}));
@@ -717,9 +732,8 @@
TEST_P(VertexFormatTest, Float16x4) {
// Fails on NVIDIA's Vulkan drivers on CQ but passes locally.
+ // TODO(dawn:1566) Might pass when using rectify_f32?
DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsNvidia());
- // TODO(dawn:1566) Fails on Arm-based Android devices, when using -0.0.
- DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());
std::vector<uint16_t> vertexData = Float32ToFloat16(std::vector<float>(
{+0.0f, -16.8f, 18.2f, -0.0f, 12.5f, 1.3f, 14.8f, -12.4f, 22.5f, -48.8f, 47.4f, -24.8f}));
@@ -727,9 +741,9 @@
DoVertexFormatTest(wgpu::VertexFormat::Float16x4, vertexData, vertexData);
}
TEST_P(VertexFormatTest, Float32_Zeros) {
- // TODO(dawn:1566) Fails on Qualcomm-based and Arm-base Android devices. When using -0.0.
+ // TODO(dawn:1566) Fails on Qualcomm-based Android devices. When using -0.0.
+ // This might pass now that we use rectify_f32?
DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsQualcomm());
- DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());
std::vector<float> vertexData = {1.3f, +0.0f, -0.0f};
@@ -746,12 +760,11 @@
TEST_P(VertexFormatTest, Float32x2) {
// Fails on NVIDIA's Vulkan drivers on CQ but passes locally.
+ // TODO(dawn:1566) This might pass now that we use rectify_f32?
DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsNvidia());
// TODO(dawn:1566) Fails on Qualcomm-based Android devices.
DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsQualcomm());
- // TODO(dawn:1566) Fails on Arm-based Android devices, when using -0.0.
- DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());
std::vector<float> vertexData = {18.23f, -0.0f, +0.0f, +1.0f, 1.3f, -1.0f};
@@ -760,9 +773,8 @@
TEST_P(VertexFormatTest, Float32x3) {
// Fails on NVIDIA's Vulkan drivers on CQ but passes locally.
+ // TODO(dawn:1566) This might pass now that we use rectify_f32?
DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsNvidia());
- // TODO(dawn:1566) Fails on Arm-based Android devices, when using -0.0.
- DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());
std::vector<float> vertexData = {
+0.0f, -1.0f, -0.0f, 1.0f, 1.3f, 99.45f, 23.6f, -81.2f, 55.0f,
@@ -772,8 +784,6 @@
}
TEST_P(VertexFormatTest, Float32x4) {
- // TODO(dawn:1566) Fails on Arm-based Android devices, when using -0.0.
- DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());
std::vector<float> vertexData = {
19.2f, -19.3f, +0.0f, 1.0f, -0.0f, 1.0f, 1.3f, -1.0f, 13.078f, 21.1965f, -1.1f, -1.2f,
};