diff options
author | Jaebaek Seo <duke.acacia@gmail.com> | 2018-11-29 16:02:15 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-29 16:02:15 -0500 |
commit | 87e0bb2e26cc4eeb5680ee30e0dcd33d24f648ac (patch) | |
tree | eedb3b2d95c400f36a335fbd1a4bd58cebd5da48 /src | |
parent | b351f069f16b27eeccf89b7e0f1723f3412f171e (diff) | |
download | amber-87e0bb2e26cc4eeb5680ee30e0dcd33d24f648ac.tar.gz |
Vulkan: update Verifier class and add its unittests (#122)
Update methods of Verifier used for comparisons to make methods
for probe frame buffer common and to support probe SSBO.
This commit is a part of PR #101
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/verifier.cc | 214 | ||||
-rw-r--r-- | src/verifier.h | 4 | ||||
-rw-r--r-- | src/verifier_test.cc | 488 |
4 files changed, 696 insertions, 11 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 074ea32..2a5809e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -77,6 +77,7 @@ set(TEST_SRCS result_test.cc shader_compiler_test.cc tokenizer_test.cc + verifier_test.cc vkscript/command_parser_test.cc vkscript/datum_type_parser_test.cc vkscript/executor_test.cc diff --git a/src/verifier.cc b/src/verifier.cc index c36923d..2f65320 100644 --- a/src/verifier.cc +++ b/src/verifier.cc @@ -16,15 +16,153 @@ #include <cmath> #include <string> +#include <vector> + +#include "src/command.h" namespace amber { namespace { -const float kEpsilon = 0.002f; +const double kEpsilon = 0.000001; +const double kDefaultTexelTolerance = 0.002; + +// It returns true if the difference is within the given error. +// If |is_tolerance_percent| is true, the actual tolerance will be +// relative value i.e., |tolerance| * fabs(real - expected). +// Otherwise, this method uses the absolute value i.e., |tolerance|. +bool IsEqualWithTolerance(const double real, + const double expected, + double tolerance, + const bool is_tolerance_percent = true) { + double difference = std::fabs(real - expected); + if (difference == 0.0) + return true; + if (is_tolerance_percent) + tolerance *= difference; + return difference < tolerance; +} -bool IsFloatPixelEqualInt(float pixel, uint8_t expected) { - // TODO(jaebaek): Change kEpsilon to tolerance. - return std::fabs(pixel - static_cast<float>(expected) / 255.0f) < kEpsilon; +template <typename T> +Result CheckValue(const ProbeSSBOCommand* command, + const uint8_t* memory, + const std::vector<Value>& values) { + const auto comp = command->GetComparator(); + const auto& tolerance = command->GetTolerances(); + const T* ptr = reinterpret_cast<const T*>(memory); + for (size_t i = 0; i < values.size(); ++i) { + const T val = values[i].IsInteger() ? static_cast<T>(values[i].AsUint64()) + : static_cast<T>(values[i].AsDouble()); + switch (comp) { + case ProbeSSBOCommand::Comparator::kEqual: + if (values[i].IsInteger()) { + if (static_cast<uint64_t>(*ptr) != static_cast<uint64_t>(val)) { + return Result("Verifier failed: " + std::to_string(*ptr) + + " == " + std::to_string(val) + ", at index " + + std::to_string(i)); + } + } else { + if (!IsEqualWithTolerance(static_cast<const double>(*ptr), + static_cast<const double>(val), kEpsilon)) { + return Result("Verifier failed: " + std::to_string(*ptr) + + " == " + std::to_string(val) + ", at index " + + std::to_string(i)); + } + } + break; + case ProbeSSBOCommand::Comparator::kNotEqual: + if (values[i].IsInteger()) { + if (static_cast<uint64_t>(*ptr) == static_cast<uint64_t>(val)) { + return Result("Verifier failed: " + std::to_string(*ptr) + + " != " + std::to_string(val) + ", at index " + + std::to_string(i)); + } + } else { + if (IsEqualWithTolerance(static_cast<const double>(*ptr), + static_cast<const double>(val), kEpsilon)) { + return Result("Verifier failed: " + std::to_string(*ptr) + + " != " + std::to_string(val) + ", at index " + + std::to_string(i)); + } + } + break; + case ProbeSSBOCommand::Comparator::kFuzzyEqual: + if (!IsEqualWithTolerance( + static_cast<const double>(*ptr), static_cast<const double>(val), + command->HasTolerances() ? tolerance[0].value : kEpsilon, + command->HasTolerances() ? tolerance[0].is_percent : true)) { + return Result("Verifier failed: " + std::to_string(*ptr) + + " ~= " + std::to_string(val) + ", at index " + + std::to_string(i)); + } + break; + case ProbeSSBOCommand::Comparator::kLess: + if (*ptr >= val) { + return Result("Verifier failed: " + std::to_string(*ptr) + " < " + + std::to_string(val) + ", at index " + + std::to_string(i)); + } + break; + case ProbeSSBOCommand::Comparator::kLessOrEqual: + if (*ptr > val) { + return Result("Verifier failed: " + std::to_string(*ptr) + + " <= " + std::to_string(val) + ", at index " + + std::to_string(i)); + } + break; + case ProbeSSBOCommand::Comparator::kGreater: + if (*ptr <= val) { + return Result("Verifier failed: " + std::to_string(*ptr) + " > " + + std::to_string(val) + ", at index " + + std::to_string(i)); + } + break; + case ProbeSSBOCommand::Comparator::kGreaterOrEqual: + if (*ptr < val) { + return Result("Verifier failed: " + std::to_string(*ptr) + + " >= " + std::to_string(val) + ", at index " + + std::to_string(i)); + } + break; + } + ++ptr; + } + return {}; +} + +void SetupToleranceForTexels(const ProbeCommand* command, + double* tolerance, + bool* is_tolerance_percent) { + if (command->HasTolerances()) { + const auto& tol = command->GetTolerances(); + if (tol.size() == 4) { + tolerance[0] = tol[0].value; + tolerance[1] = tol[1].value; + tolerance[2] = tol[2].value; + tolerance[3] = tol[3].value; + is_tolerance_percent[0] = tol[0].is_percent; + is_tolerance_percent[1] = tol[1].is_percent; + is_tolerance_percent[2] = tol[2].is_percent; + is_tolerance_percent[3] = tol[3].is_percent; + } else { + tolerance[0] = tol[0].value; + tolerance[1] = tol[0].value; + tolerance[2] = tol[0].value; + tolerance[3] = tol[0].value; + is_tolerance_percent[0] = tol[0].is_percent; + is_tolerance_percent[1] = tol[0].is_percent; + is_tolerance_percent[2] = tol[0].is_percent; + is_tolerance_percent[3] = tol[0].is_percent; + } + } else { + tolerance[0] = kDefaultTexelTolerance; + tolerance[1] = kDefaultTexelTolerance; + tolerance[2] = kDefaultTexelTolerance; + tolerance[3] = kDefaultTexelTolerance; + is_tolerance_percent[0] = false; + is_tolerance_percent[1] = false; + is_tolerance_percent[2] = false; + is_tolerance_percent[3] = false; + } } } // namespace @@ -65,6 +203,10 @@ Result Verifier::Probe(const ProbeCommand* command, std::to_string(frame_width) + "," + std::to_string(frame_height) + ")"); } + double tolerance[4] = {}; + bool is_tolerance_percent[4] = {}; + SetupToleranceForTexels(command, tolerance, is_tolerance_percent); + // TODO(jaebaek): Support all VkFormat const uint8_t* ptr = static_cast<const uint8_t*>(buf); uint32_t count_of_invalid_pixels = 0; @@ -74,11 +216,23 @@ Result Verifier::Probe(const ProbeCommand* command, const uint8_t* p = ptr + stride * frame_width * (j + y) + stride * x; for (uint32_t i = 0; i < width; ++i) { // TODO(jaebaek): Get actual pixel values based on frame buffer formats. - if (!IsFloatPixelEqualInt(command->GetR(), p[stride * i]) || - !IsFloatPixelEqualInt(command->GetG(), p[stride * i + 1]) || - !IsFloatPixelEqualInt(command->GetB(), p[stride * i + 2]) || + if (!IsEqualWithTolerance( + static_cast<const double>(command->GetR()), + static_cast<const double>(p[stride * i]) / 255.0, tolerance[0], + is_tolerance_percent[0]) || + !IsEqualWithTolerance( + static_cast<const double>(command->GetG()), + static_cast<const double>(p[stride * i + 1]) / 255.0, + tolerance[1], is_tolerance_percent[1]) || + !IsEqualWithTolerance( + static_cast<const double>(command->GetB()), + static_cast<const double>(p[stride * i + 2]) / 255.0, + tolerance[2], is_tolerance_percent[2]) || (command->IsRGBA() && - !IsFloatPixelEqualInt(command->GetA(), p[stride * i + 3]))) { + !IsEqualWithTolerance( + static_cast<const double>(command->GetA()), + static_cast<const double>(p[stride * i + 3]) / 255.0, + tolerance[3], is_tolerance_percent[3]))) { if (!count_of_invalid_pixels) { first_invalid_i = i; first_invalid_j = j; @@ -114,8 +268,48 @@ Result Verifier::Probe(const ProbeCommand* command, return {}; } -Result Verifier::ProbeSSBO(const ProbeSSBOCommand*, size_t, const void*) { - return Result("Verifier::ProbeSSBO Not Implemented"); +Result Verifier::ProbeSSBO(const ProbeSSBOCommand* command, + size_t size_in_bytes, + const void* cpu_memory) { + const auto& values = command->GetValues(); + const auto& datum_type = command->GetDatumType(); + size_t bytes_per_elem = datum_type.SizeInBytes() / datum_type.RowCount() / + datum_type.ColumnCount(); + size_t offset = static_cast<size_t>(command->GetOffset()); + + if (values.size() * bytes_per_elem + offset > size_in_bytes) { + return Result( + "Verifier::ProbeSSBO has more expected values than SSBO size"); + } + + if (offset % bytes_per_elem != 0) { + return Result( + "Verifier::ProbeSSBO given offset is not multiple of bytes_per_elem"); + } + + const uint8_t* ptr = static_cast<const uint8_t*>(cpu_memory) + offset; + if (datum_type.IsInt8()) + return CheckValue<int8_t>(command, ptr, values); + if (datum_type.IsUint8()) + return CheckValue<uint8_t>(command, ptr, values); + if (datum_type.IsInt16()) + return CheckValue<int16_t>(command, ptr, values); + if (datum_type.IsUint16()) + return CheckValue<uint16_t>(command, ptr, values); + if (datum_type.IsInt32()) + return CheckValue<int32_t>(command, ptr, values); + if (datum_type.IsUint32()) + return CheckValue<uint32_t>(command, ptr, values); + if (datum_type.IsInt64()) + return CheckValue<int64_t>(command, ptr, values); + if (datum_type.IsUint64()) + return CheckValue<uint64_t>(command, ptr, values); + if (datum_type.IsFloat()) + return CheckValue<float>(command, ptr, values); + if (datum_type.IsDouble()) + return CheckValue<double>(command, ptr, values); + + return Result("Verifier::ProbeSSBO unknown datum type"); } } // namespace amber diff --git a/src/verifier.h b/src/verifier.h index 40610a9..cbe0dc2 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -30,7 +30,9 @@ class Verifier { uint32_t frame_width, uint32_t frame_height, const void* buf); - Result ProbeSSBO(const ProbeSSBOCommand*, size_t, const void*); + Result ProbeSSBO(const ProbeSSBOCommand*, + size_t size, + const void* cpu_memory); }; } // namespace amber diff --git a/src/verifier_test.cc b/src/verifier_test.cc new file mode 100644 index 0000000..7161c9d --- /dev/null +++ b/src/verifier_test.cc @@ -0,0 +1,488 @@ +// Copyright 2018 The Amber Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <memory> +#include <utility> +#include <vector> + +#include "amber/result.h" +#include "gtest/gtest.h" +#include "src/command.h" +#include "src/datum_type.h" +#include "src/value.h" +#include "src/verifier.h" + +namespace amber { + +using VerifierTest = testing::Test; + +TEST_F(VerifierTest, ProbeFrameBufferWholeWindow) { + ProbeCommand probe; + probe.SetWholeWindow(); + probe.SetIsRGBA(); + probe.SetR(0.5f); + probe.SetG(0.25f); + probe.SetB(0.2f); + probe.SetA(0.8f); + + EXPECT_TRUE(probe.IsWholeWindow()); + EXPECT_TRUE(probe.IsRGBA()); + EXPECT_FLOAT_EQ(0.5f, probe.GetR()); + EXPECT_FLOAT_EQ(0.25f, probe.GetG()); + EXPECT_FLOAT_EQ(0.2f, probe.GetB()); + EXPECT_FLOAT_EQ(0.8f, probe.GetA()); + + const uint8_t frame_buffer[3][3][4] = { + { + {128, 64, 51, 204}, + {128, 64, 51, 204}, + {128, 64, 51, 204}, + }, + { + {128, 64, 51, 204}, + {128, 64, 51, 204}, + {128, 64, 51, 204}, + }, + { + {128, 64, 51, 204}, + {128, 64, 51, 204}, + {128, 64, 51, 204}, + }, + }; + + Verifier verifier; + Result r = + verifier.Probe(&probe, 4, 3, 3, static_cast<const void*>(frame_buffer)); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeFrameBufferRelative) { + ProbeCommand probe; + probe.SetRelative(); + probe.SetIsRGBA(); + probe.SetX(0.1f); + probe.SetY(0.2f); + probe.SetWidth(0.4f); + probe.SetHeight(0.6f); + probe.SetR(0.5f); + probe.SetG(0.25f); + probe.SetB(0.2f); + probe.SetA(0.8f); + + EXPECT_FALSE(probe.IsWholeWindow()); + EXPECT_TRUE(probe.IsRelative()); + EXPECT_TRUE(probe.IsRGBA()); + EXPECT_FLOAT_EQ(0.1f, probe.GetX()); + EXPECT_FLOAT_EQ(0.2f, probe.GetY()); + EXPECT_FLOAT_EQ(0.4f, probe.GetWidth()); + EXPECT_FLOAT_EQ(0.6f, probe.GetHeight()); + EXPECT_FLOAT_EQ(0.5f, probe.GetR()); + EXPECT_FLOAT_EQ(0.25f, probe.GetG()); + EXPECT_FLOAT_EQ(0.2f, probe.GetB()); + EXPECT_FLOAT_EQ(0.8f, probe.GetA()); + + uint8_t frame_buffer[10][10][4] = {}; + for (uint8_t x = 1; x < 5; ++x) { + for (uint8_t y = 2; y < 8; ++y) { + frame_buffer[y][x][0] = 128; + frame_buffer[y][x][1] = 64; + frame_buffer[y][x][2] = 51; + frame_buffer[y][x][3] = 204; + } + } + + Verifier verifier; + Result r = + verifier.Probe(&probe, 4, 10, 10, static_cast<const void*>(frame_buffer)); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeFrameBuffer) { + ProbeCommand probe; + probe.SetIsRGBA(); + probe.SetX(1.0f); + probe.SetY(2.0f); + probe.SetWidth(4.0f); + probe.SetHeight(6.0f); + probe.SetR(0.5f); + probe.SetG(0.25f); + probe.SetB(0.2f); + probe.SetA(0.8f); + + EXPECT_FALSE(probe.IsWholeWindow()); + EXPECT_FALSE(probe.IsRelative()); + EXPECT_TRUE(probe.IsRGBA()); + EXPECT_FLOAT_EQ(1.0f, probe.GetX()); + EXPECT_FLOAT_EQ(2.0f, probe.GetY()); + EXPECT_FLOAT_EQ(4.0f, probe.GetWidth()); + EXPECT_FLOAT_EQ(6.0f, probe.GetHeight()); + EXPECT_FLOAT_EQ(0.5f, probe.GetR()); + EXPECT_FLOAT_EQ(0.25f, probe.GetG()); + EXPECT_FLOAT_EQ(0.2f, probe.GetB()); + EXPECT_FLOAT_EQ(0.8f, probe.GetA()); + + uint8_t frame_buffer[10][10][4] = {}; + for (uint8_t x = 1; x < 5; ++x) { + for (uint8_t y = 2; y < 8; ++y) { + frame_buffer[y][x][0] = 128; + frame_buffer[y][x][1] = 64; + frame_buffer[y][x][2] = 51; + frame_buffer[y][x][3] = 204; + } + } + + Verifier verifier; + Result r = + verifier.Probe(&probe, 4, 10, 10, static_cast<const void*>(frame_buffer)); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeFrameBufferRGB) { + ProbeCommand probe; + probe.SetWholeWindow(); + probe.SetR(0.5f); + probe.SetG(0.25f); + probe.SetB(0.2f); + + EXPECT_TRUE(probe.IsWholeWindow()); + EXPECT_FALSE(probe.IsRelative()); + EXPECT_FALSE(probe.IsRGBA()); + EXPECT_FLOAT_EQ(0.5f, probe.GetR()); + EXPECT_FLOAT_EQ(0.25f, probe.GetG()); + EXPECT_FLOAT_EQ(0.2f, probe.GetB()); + EXPECT_FLOAT_EQ(0.0f, probe.GetA()); + + const uint8_t frame_buffer[3][3][4] = { + { + {128, 64, 51, 255}, + {128, 64, 51, 255}, + {128, 64, 51, 255}, + }, + { + {128, 64, 51, 255}, + {128, 64, 51, 255}, + {128, 64, 51, 255}, + }, + { + {128, 64, 51, 255}, + {128, 64, 51, 255}, + {128, 64, 51, 255}, + }, + }; + + Verifier verifier; + Result r = + verifier.Probe(&probe, 4, 3, 3, static_cast<const void*>(frame_buffer)); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBOUint8Single) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kUint8); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.emplace_back(); + values.back().SetIntValue(13); + probe_ssbo.SetValues(std::move(values)); + + uint8_t ssbo = 13U; + + Verifier verifier; + Result r = verifier.ProbeSSBO(&probe_ssbo, sizeof(uint8_t), + static_cast<const void*>(&ssbo)); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBOUint8Multiple) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kUint8); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.resize(3); + values[0].SetIntValue(2); + values[1].SetIntValue(0); + values[2].SetIntValue(10); + probe_ssbo.SetValues(std::move(values)); + + const uint8_t ssbo[3] = {2U, 0U, 10U}; + + Verifier verifier; + Result r = verifier.ProbeSSBO(&probe_ssbo, sizeof(uint8_t) * 3, ssbo); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBOUint8Many) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kUint8); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.resize(200); + for (size_t i = 0; i < values.size(); ++i) { + values[i].SetIntValue(255 - i); + } + probe_ssbo.SetValues(std::move(values)); + + std::vector<uint8_t> ssbo; + ssbo.resize(200); + for (size_t i = 0; i < ssbo.size(); ++i) { + ssbo[i] = static_cast<uint8_t>(255U) - static_cast<uint8_t>(i); + } + + Verifier verifier; + Result r = verifier.ProbeSSBO(&probe_ssbo, sizeof(uint8_t) * ssbo.size(), + ssbo.data()); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBOUint32Single) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kUint32); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.emplace_back(); + values.back().SetIntValue(13); + probe_ssbo.SetValues(std::move(values)); + + uint32_t ssbo = 13U; + + Verifier verifier; + Result r = verifier.ProbeSSBO(&probe_ssbo, sizeof(uint32_t), + static_cast<const void*>(&ssbo)); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBOUint32Multiple) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kUint32); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.resize(4); + values[0].SetIntValue(2); + values[1].SetIntValue(0); + values[2].SetIntValue(10); + values[3].SetIntValue(1234); + probe_ssbo.SetValues(std::move(values)); + + const uint32_t ssbo[4] = {2U, 0U, 10U, 1234U}; + + Verifier verifier; + Result r = verifier.ProbeSSBO(&probe_ssbo, sizeof(uint32_t) * 4, ssbo); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBOUint32Many) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kUint32); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.resize(200); + for (size_t i = 0; i < values.size(); ++i) { + values[i].SetIntValue(i * i); + } + probe_ssbo.SetValues(std::move(values)); + + std::vector<uint32_t> ssbo; + ssbo.resize(200); + for (size_t i = 0; i < ssbo.size(); ++i) { + ssbo[i] = static_cast<uint32_t>(i) * static_cast<uint32_t>(i); + } + + Verifier verifier; + Result r = verifier.ProbeSSBO(&probe_ssbo, sizeof(uint32_t) * ssbo.size(), + ssbo.data()); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBOFloatSingle) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kFloat); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.emplace_back(); + values.back().SetDoubleValue(13.7); + probe_ssbo.SetValues(std::move(values)); + + float ssbo = 13.7f; + + Verifier verifier; + Result r = verifier.ProbeSSBO(&probe_ssbo, sizeof(float), + static_cast<const void*>(&ssbo)); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBOFloatMultiple) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kFloat); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.resize(4); + values[0].SetDoubleValue(2.9); + values[1].SetDoubleValue(0.73); + values[2].SetDoubleValue(10.0); + values[3].SetDoubleValue(1234.56); + probe_ssbo.SetValues(std::move(values)); + + const float ssbo[4] = {2.9f, 0.73f, 10.0f, 1234.56f}; + + Verifier verifier; + Result r = verifier.ProbeSSBO(&probe_ssbo, sizeof(float) * 4, ssbo); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBOFloatMany) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kFloat); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.resize(200); + for (size_t i = 0; i < values.size(); ++i) { + values[i].SetDoubleValue(static_cast<double>(i) / 1.7); + } + probe_ssbo.SetValues(std::move(values)); + + std::vector<float> ssbo; + ssbo.resize(200); + for (size_t i = 0; i < ssbo.size(); ++i) { + ssbo[i] = static_cast<float>(static_cast<double>(i) / 1.7); + } + + Verifier verifier; + Result r = + verifier.ProbeSSBO(&probe_ssbo, sizeof(float) * ssbo.size(), ssbo.data()); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBODoubleSingle) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kDouble); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.emplace_back(); + values.back().SetDoubleValue(13.7); + probe_ssbo.SetValues(std::move(values)); + + double ssbo = 13.7; + + Verifier verifier; + Result r = verifier.ProbeSSBO(&probe_ssbo, sizeof(double), + static_cast<const void*>(&ssbo)); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBODoubleMultiple) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kDouble); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.resize(4); + values[0].SetDoubleValue(2.9); + values[1].SetDoubleValue(0.73); + values[2].SetDoubleValue(10.0); + values[3].SetDoubleValue(1234.56); + probe_ssbo.SetValues(std::move(values)); + + const double ssbo[4] = {2.9, 0.73, 10.0, 1234.56}; + + Verifier verifier; + Result r = verifier.ProbeSSBO(&probe_ssbo, sizeof(double) * 4, ssbo); + EXPECT_TRUE(r.IsSuccess()); +} + +TEST_F(VerifierTest, ProbeSSBODoubleMany) { + ProbeSSBOCommand probe_ssbo; + + DatumType datum_type; + datum_type.SetType(DataType::kDouble); + probe_ssbo.SetDatumType(datum_type); + + probe_ssbo.SetComparator(ProbeSSBOCommand::Comparator::kEqual); + + std::vector<Value> values; + values.resize(200); + for (size_t i = 0; i < values.size(); ++i) { + values[i].SetDoubleValue(static_cast<double>(i) / 1.7); + } + probe_ssbo.SetValues(std::move(values)); + + std::vector<double> ssbo; + ssbo.resize(200); + for (size_t i = 0; i < ssbo.size(); ++i) { + ssbo[i] = static_cast<double>(i) / 1.7; + } + + Verifier verifier; + Result r = verifier.ProbeSSBO(&probe_ssbo, sizeof(double) * ssbo.size(), + ssbo.data()); + EXPECT_TRUE(r.IsSuccess()); +} + +// TODO(jaebaek): Test all ProbeSSBOCommand::Comparator and +// all primitive types and tolerance. + +} // namespace amber |