chromium/third_party/dawn/src/dawn/tests/DawnTest.h

// Copyright 2017 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef SRC_DAWN_TESTS_DAWNTEST_H_
#define SRC_DAWN_TESTS_DAWNTEST_H_

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <webgpu/webgpu_cpp.h>

#include <atomic>
#include <memory>
#include <queue>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "dawn/common/Log.h"
#include "dawn/common/Mutex.h"
#include "dawn/common/Platform.h"
#include "dawn/common/Preprocessor.h"
#include "dawn/dawn_proc_table.h"
#include "dawn/native/DawnNative.h"
#include "dawn/platform/DawnPlatform.h"
#include "dawn/tests/AdapterTestConfig.h"
#include "dawn/tests/MockCallback.h"
#include "dawn/tests/ParamGenerator.h"
#include "dawn/tests/ToggleParser.h"
#include "dawn/utils/TestUtils.h"
#include "dawn/utils/TextureUtils.h"
#include "dawn/webgpu_cpp_print.h"
#include "partition_alloc/pointers/raw_ptr.h"

// Getting data back from Dawn is done in an async manners so all expectations are "deferred"
// until the end of the test. Also expectations use a copy to a MapRead buffer to get the data
// so resources should have the CopySrc allowed usage bit if you want to add expectations on
// them.

// AddBufferExpectation is defined in DawnTestBase as protected function. This ensures the macro can
// only be used in derivd class of DawnTestBase. Use "this" pointer to ensure the macro works with
// CRTP.
#define EXPECT_BUFFER(buffer, offset, size, expectation)

#define EXPECT_BUFFER_U8_EQ(expected, buffer, offset)

#define EXPECT_BUFFER_U8_RANGE_EQ(expected, buffer, offset, count)

#define EXPECT_BUFFER_U16_EQ(expected, buffer, offset)

#define EXPECT_BUFFER_U16_RANGE_EQ(expected, buffer, offset, count)

#define EXPECT_BUFFER_U32_EQ(expected, buffer, offset)

#define EXPECT_BUFFER_U32_RANGE_EQ(expected, buffer, offset, count)

#define EXPECT_BUFFER_U64_EQ(expected, buffer, offset)

#define EXPECT_BUFFER_U64_RANGE_EQ(expected, buffer, offset, count)

#define EXPECT_BUFFER_FLOAT_EQ(expected, buffer, offset)

#define EXPECT_BUFFER_FLOAT_RANGE_EQ(expected, buffer, offset, count)

// Test a pixel of the mip level 0 of a 2D texture.
#define EXPECT_PIXEL_RGBA8_EQ(expected, texture, x, y)

#define EXPECT_PIXEL_FLOAT_EQ(expected, texture, x, y)

#define EXPECT_PIXEL_FLOAT16_EQ(expected, texture, x, y)

#define EXPECT_PIXEL_RGBA8_BETWEEN(color0, color1, texture, x, y)

#define EXPECT_TEXTURE_EQ(...)

#define EXPECT_TEXTURE_FLOAT16_EQ(...)

// Matcher for C++ types to verify that their internal C-handles are identical.
MATCHER_P(CHandleIs, cType, "") {}

#define ASSERT_DEVICE_ERROR_MSG_ON(device, statement, matcher)

#define ASSERT_DEVICE_ERROR_MSG(statement, matcher)

#define ASSERT_DEVICE_ERROR_ON(device, statement)

#define ASSERT_DEVICE_ERROR(statement)

struct GLFWwindow;

void InitDawnEnd2EndTestEnvironment(int argc, char** argv);

namespace dawn {
namespace utils {
class PlatformDebugLogger;
class TerribleCommandBuffer;
class WireHelper;
}  // namespace utils

namespace detail {
class Expectation;
class CustomTextureExpectation;

template <typename T>
class ExpectConstant;
template <typename T, typename U = T>
class ExpectEq;
template <typename T>
class ExpectBetweenColors;
}  // namespace detail

namespace wire {
class CommandHandler;
class WireClient;
class WireServer;
}  // namespace wire

class DawnTestEnvironment : public testing::Environment {};

class DawnTestBase {};

#define DAWN_SKIP_TEST_IF_BASE(condition, type, reason)

// Skip a test which requires a feature or a toggle to be present / not present or some WIP
// features.
#define DAWN_TEST_UNSUPPORTED_IF(condition)

// Skip a test when the test failing on a specific HW / backend / OS combination. We can disable
// this macro with the command line parameter "--run-suppressed-tests".
#define DAWN_SUPPRESS_TEST_IF(condition)

#define EXPECT_DEPRECATION_WARNINGS(statement, n)
#define EXPECT_DEPRECATION_WARNING(statement)

template <typename Params = AdapterTestParam>
class DawnTestWithParams : public DawnTestBase, public ::testing::TestWithParam<Params> {};

template <typename Params>
DawnTestWithParams<Params>::DawnTestWithParams() :{}

DawnTest;

// Instantiate the test once for each backend provided after the first argument. Use it like this:
//     DAWN_INSTANTIATE_TEST(MyTestFixture, MetalBackend, OpenGLBackend)
#define DAWN_INSTANTIATE_TEST(testName, ...)

#define DAWN_INSTANTIATE_PREFIXED_TEST_P(prefix, testName, ...)

// Instantiate the test once for each backend provided in the first param list.
// The test will be parameterized over the following param lists.
// Use it like this:
//     DAWN_INSTANTIATE_TEST_P(MyTestFixture, {MetalBackend(), OpenGLBackend()}, {A, B}, {1, 2})
// MyTestFixture must extend DawnTestWithParams<Param> where Param is a struct that extends
// AdapterTestParam, and whose constructor looks like:
//     Param(AdapterTestParam, ABorC, 12or3, ..., otherParams... )
//     You must also teach GTest how to print this struct.
//     https://github.com/google/googletest/blob/main/docs/advanced.md#teaching-googletest-how-to-print-your-values
// Macro DAWN_TEST_PARAM_STRUCT can help generate this struct.
#define DAWN_INSTANTIATE_TEST_P(testName, ...)

// Basically same as DAWN_INSTANTIATE_TEST_P, except that each backend is provided in the
// 'backends' param list.
#define DAWN_INSTANTIATE_TEST_B(testName, backends, ...)

// Usage: DAWN_TEST_PARAM_STRUCT(Foo, TypeA, TypeB, ...)
// Generate a test param struct called Foo which extends AdapterTestParam and generated
// struct _Dawn_Foo. _Dawn_Foo has members of types TypeA, TypeB, etc. which are named mTypeA,
// mTypeB, etc. in the order they are placed in the macro argument list. Struct Foo should be
// constructed with an AdapterTestParam as the first argument, followed by a list of values
// to initialize the base _Dawn_Foo struct.
// It is recommended to use alias declarations so that stringified types are more readable.
// Example:
//   using MyParam = unsigned int;
//   DAWN_TEST_PARAM_STRUCT(FooParams, MyParam);
#define DAWN_TEST_PARAM_STRUCT(StructName, ...)

namespace detail {
// Helper functions used for DAWN_INSTANTIATE_TEST
std::vector<AdapterTestParam> GetAvailableAdapterTestParamsForBackends(
    const BackendTestConfig* params,
    size_t numParams);

// All classes used to implement the deferred expectations should inherit from this.
class Expectation {};

template <typename T>
class ExpectConstant : public Expectation {};

extern template class ExpectConstant<float>;

// Expectation that checks the data is equal to some expected values.
// T - expected value Type
// U - actual value Type (defaults = T)
// This is expanded for float16 mostly where T=float, U=uint16_t
template <typename T, typename U>
class ExpectEq : public Expectation {};
extern template class ExpectEq<uint8_t>;
extern template class ExpectEq<int16_t>;
extern template class ExpectEq<uint32_t>;
extern template class ExpectEq<uint64_t>;
extern template class ExpectEq<int32_t>;
extern template class ExpectEq<utils::RGBA8>;
extern template class ExpectEq<float>;
extern template class ExpectEq<float, uint16_t>;

template <typename T>
class ExpectBetweenColors : public Expectation {};
// A color is considered between color0 and color1 when all channel values are within range of
// each counterparts. It doesn't matter which value is higher or lower. Essentially color =
// lerp(color0, color1, t) where t is [0,1]. But I don't want to be too strict here.
extern template class ExpectBetweenColors<utils::RGBA8>;

class CustomTextureExpectation : public Expectation {};

}  // namespace detail

template <typename Param, typename... Params>
auto MakeParamGenerator(std::vector<BackendTestConfig>&& first,
                        std::initializer_list<Params>&&... params) {}
template <typename Param, typename... Params>
auto MakeParamGenerator(std::vector<BackendTestConfig>&& first, std::vector<Params>&&... params) {}

}  // namespace dawn
#endif  // SRC_DAWN_TESTS_DAWNTEST_H_