Corentin Wallez | 4a9ef4e | 2018-07-18 11:40:26 +0200 | [diff] [blame] | 1 | // Copyright 2017 The Dawn Authors |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
Corentin Wallez | a4da032 | 2018-07-18 15:18:25 +0200 | [diff] [blame] | 15 | #include "tests/DawnTest.h" |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 16 | |
Corentin Wallez | fd589f3 | 2017-07-10 13:46:05 -0400 | [diff] [blame] | 17 | #include "common/Assert.h" |
Brandon Jones | d1cba10 | 2020-01-07 17:49:15 +0000 | [diff] [blame] | 18 | #include "common/GPUInfo.h" |
Corentin Wallez | 95586ff | 2019-12-05 11:13:01 +0000 | [diff] [blame] | 19 | #include "common/Log.h" |
Austin Eng | 51ff013 | 2017-07-13 15:10:30 -0400 | [diff] [blame] | 20 | #include "common/Math.h" |
Jiawei Shao | 58809d4 | 2018-09-19 00:32:52 +0000 | [diff] [blame] | 21 | #include "common/Platform.h" |
Austin Eng | cbc206e | 2019-12-10 23:32:48 +0000 | [diff] [blame] | 22 | #include "common/SystemUtils.h" |
Corentin Wallez | 9649682 | 2019-10-15 11:44:38 +0000 | [diff] [blame] | 23 | #include "dawn/dawn_proc.h" |
Austin Eng | e2c8513 | 2019-02-11 21:50:16 +0000 | [diff] [blame] | 24 | #include "dawn_wire/WireClient.h" |
| 25 | #include "dawn_wire/WireServer.h" |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 26 | #include "utils/ComboRenderPipelineDescriptor.h" |
Austin Eng | f580096 | 2020-08-14 21:02:12 +0000 | [diff] [blame] | 27 | #include "utils/PlatformDebugLogger.h" |
Corentin Wallez | 134e080 | 2017-07-17 17:13:57 -0400 | [diff] [blame] | 28 | #include "utils/SystemUtils.h" |
Corentin Wallez | bdc8677 | 2018-07-26 15:07:57 +0200 | [diff] [blame] | 29 | #include "utils/TerribleCommandBuffer.h" |
Kai Ninomiya | c9d0b49 | 2020-10-23 21:21:33 +0000 | [diff] [blame] | 30 | #include "utils/TestUtils.h" |
Corentin Wallez | 04863c4 | 2019-10-25 11:36:47 +0000 | [diff] [blame] | 31 | #include "utils/WGPUHelpers.h" |
Austin Eng | e58d5a3 | 2021-01-27 22:54:04 +0000 | [diff] [blame] | 32 | #include "utils/WireHelper.h" |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 33 | |
Corentin Wallez | bb5696b | 2019-02-12 15:48:15 +0000 | [diff] [blame] | 34 | #include <algorithm> |
Austin Eng | cbc206e | 2019-12-10 23:32:48 +0000 | [diff] [blame] | 35 | #include <fstream> |
Corentin Wallez | fda0617 | 2019-02-21 17:36:11 +0000 | [diff] [blame] | 36 | #include <iomanip> |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 37 | #include <regex> |
Corentin Wallez | fda0617 | 2019-02-21 17:36:11 +0000 | [diff] [blame] | 38 | #include <sstream> |
Corentin Wallez | 8c88e1d | 2019-02-05 12:17:20 +0000 | [diff] [blame] | 39 | #include <unordered_map> |
Brian Ho | 2fb628d | 2019-08-13 21:45:44 +0000 | [diff] [blame] | 40 | |
Austin Eng | f580096 | 2020-08-14 21:02:12 +0000 | [diff] [blame] | 41 | #if defined(DAWN_ENABLE_BACKEND_OPENGL) |
Brian Ho | 2fb628d | 2019-08-13 21:45:44 +0000 | [diff] [blame] | 42 | # include "GLFW/glfw3.h" |
| 43 | # include "dawn_native/OpenGLBackend.h" |
| 44 | #endif // DAWN_ENABLE_BACKEND_OPENGL |
Corentin Wallez | 419e984 | 2018-06-07 13:10:44 +0200 | [diff] [blame] | 45 | |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 46 | namespace { |
| 47 | |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 48 | std::string ParamName(wgpu::BackendType type) { |
Corentin Wallez | a4da032 | 2018-07-18 15:18:25 +0200 | [diff] [blame] | 49 | switch (type) { |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 50 | case wgpu::BackendType::D3D12: |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 51 | return "D3D12"; |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 52 | case wgpu::BackendType::Metal: |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 53 | return "Metal"; |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 54 | case wgpu::BackendType::Null: |
Corentin Wallez | 8c88e1d | 2019-02-05 12:17:20 +0000 | [diff] [blame] | 55 | return "Null"; |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 56 | case wgpu::BackendType::OpenGL: |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 57 | return "OpenGL"; |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 58 | case wgpu::BackendType::OpenGLES: |
| 59 | return "OpenGLES"; |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 60 | case wgpu::BackendType::Vulkan: |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 61 | return "Vulkan"; |
| 62 | default: |
Corentin Wallez | 8fca4a2 | 2017-07-10 21:48:12 -0400 | [diff] [blame] | 63 | UNREACHABLE(); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 64 | } |
| 65 | } |
| 66 | |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 67 | const char* AdapterTypeName(wgpu::AdapterType type) { |
Corentin Wallez | 2ec74dc | 2019-04-15 16:36:25 +0000 | [diff] [blame] | 68 | switch (type) { |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 69 | case wgpu::AdapterType::DiscreteGPU: |
Corentin Wallez | 2ec74dc | 2019-04-15 16:36:25 +0000 | [diff] [blame] | 70 | return "Discrete GPU"; |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 71 | case wgpu::AdapterType::IntegratedGPU: |
Corentin Wallez | 2ec74dc | 2019-04-15 16:36:25 +0000 | [diff] [blame] | 72 | return "Integrated GPU"; |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 73 | case wgpu::AdapterType::CPU: |
Corentin Wallez | 2ec74dc | 2019-04-15 16:36:25 +0000 | [diff] [blame] | 74 | return "CPU"; |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 75 | case wgpu::AdapterType::Unknown: |
Corentin Wallez | 2ec74dc | 2019-04-15 16:36:25 +0000 | [diff] [blame] | 76 | return "Unknown"; |
| 77 | default: |
| 78 | UNREACHABLE(); |
| 79 | } |
| 80 | } |
| 81 | |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 82 | struct MapReadUserdata { |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 83 | DawnTestBase* test; |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 84 | size_t slot; |
| 85 | }; |
Corentin Wallez | 79aee9c | 2018-10-16 09:16:15 +0000 | [diff] [blame] | 86 | |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 87 | DawnTestEnvironment* gTestEnv = nullptr; |
| 88 | |
shrekshao | f8c5e4a | 2020-12-24 03:11:17 +0000 | [diff] [blame] | 89 | template <typename T> |
| 90 | void printBuffer(testing::AssertionResult& result, const T* buffer, const size_t count) { |
| 91 | static constexpr unsigned int kBytes = sizeof(T); |
| 92 | |
| 93 | for (size_t index = 0; index < count; ++index) { |
| 94 | auto byteView = reinterpret_cast<const uint8_t*>(buffer + index); |
| 95 | for (unsigned int b = 0; b < kBytes; ++b) { |
| 96 | char buf[4]; |
| 97 | sprintf(buf, "%02X ", byteView[b]); |
| 98 | result << buf; |
| 99 | } |
| 100 | } |
| 101 | result << std::endl; |
| 102 | } |
| 103 | |
Austin Eng | f580096 | 2020-08-14 21:02:12 +0000 | [diff] [blame] | 104 | } // anonymous namespace |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 105 | |
Yunchao He | 0c02f54 | 2019-11-19 17:57:30 +0000 | [diff] [blame] | 106 | const RGBA8 RGBA8::kZero = RGBA8(0, 0, 0, 0); |
| 107 | const RGBA8 RGBA8::kBlack = RGBA8(0, 0, 0, 255); |
| 108 | const RGBA8 RGBA8::kRed = RGBA8(255, 0, 0, 255); |
| 109 | const RGBA8 RGBA8::kGreen = RGBA8(0, 255, 0, 255); |
| 110 | const RGBA8 RGBA8::kBlue = RGBA8(0, 0, 255, 255); |
| 111 | const RGBA8 RGBA8::kYellow = RGBA8(255, 255, 0, 255); |
| 112 | const RGBA8 RGBA8::kWhite = RGBA8(255, 255, 255, 255); |
| 113 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 114 | BackendTestConfig::BackendTestConfig(wgpu::BackendType backendType, |
| 115 | std::initializer_list<const char*> forceEnabledWorkarounds, |
| 116 | std::initializer_list<const char*> forceDisabledWorkarounds) |
Austin Eng | 6c1d646 | 2020-02-25 16:23:17 +0000 | [diff] [blame] | 117 | : backendType(backendType), |
| 118 | forceEnabledWorkarounds(forceEnabledWorkarounds), |
| 119 | forceDisabledWorkarounds(forceDisabledWorkarounds) { |
| 120 | } |
Jiawei Shao | 93373ab | 2019-05-29 00:07:37 +0000 | [diff] [blame] | 121 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 122 | BackendTestConfig D3D12Backend(std::initializer_list<const char*> forceEnabledWorkarounds, |
| 123 | std::initializer_list<const char*> forceDisabledWorkarounds) { |
| 124 | return BackendTestConfig(wgpu::BackendType::D3D12, forceEnabledWorkarounds, |
| 125 | forceDisabledWorkarounds); |
Austin Eng | 6c1d646 | 2020-02-25 16:23:17 +0000 | [diff] [blame] | 126 | } |
| 127 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 128 | BackendTestConfig MetalBackend(std::initializer_list<const char*> forceEnabledWorkarounds, |
| 129 | std::initializer_list<const char*> forceDisabledWorkarounds) { |
| 130 | return BackendTestConfig(wgpu::BackendType::Metal, forceEnabledWorkarounds, |
| 131 | forceDisabledWorkarounds); |
Austin Eng | 6c1d646 | 2020-02-25 16:23:17 +0000 | [diff] [blame] | 132 | } |
| 133 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 134 | BackendTestConfig NullBackend(std::initializer_list<const char*> forceEnabledWorkarounds, |
| 135 | std::initializer_list<const char*> forceDisabledWorkarounds) { |
| 136 | return BackendTestConfig(wgpu::BackendType::Null, forceEnabledWorkarounds, |
| 137 | forceDisabledWorkarounds); |
Corentin Wallez | 11652ff | 2020-03-20 17:07:20 +0000 | [diff] [blame] | 138 | } |
| 139 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 140 | BackendTestConfig OpenGLBackend(std::initializer_list<const char*> forceEnabledWorkarounds, |
| 141 | std::initializer_list<const char*> forceDisabledWorkarounds) { |
| 142 | return BackendTestConfig(wgpu::BackendType::OpenGL, forceEnabledWorkarounds, |
| 143 | forceDisabledWorkarounds); |
Austin Eng | 6c1d646 | 2020-02-25 16:23:17 +0000 | [diff] [blame] | 144 | } |
| 145 | |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 146 | BackendTestConfig OpenGLESBackend(std::initializer_list<const char*> forceEnabledWorkarounds, |
| 147 | std::initializer_list<const char*> forceDisabledWorkarounds) { |
| 148 | return BackendTestConfig(wgpu::BackendType::OpenGLES, forceEnabledWorkarounds, |
| 149 | forceDisabledWorkarounds); |
| 150 | } |
| 151 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 152 | BackendTestConfig VulkanBackend(std::initializer_list<const char*> forceEnabledWorkarounds, |
| 153 | std::initializer_list<const char*> forceDisabledWorkarounds) { |
| 154 | return BackendTestConfig(wgpu::BackendType::Vulkan, forceEnabledWorkarounds, |
| 155 | forceDisabledWorkarounds); |
Jiawei Shao | 15d4c2e | 2019-04-26 07:52:57 +0000 | [diff] [blame] | 156 | } |
| 157 | |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 158 | TestAdapterProperties::TestAdapterProperties(const wgpu::AdapterProperties& properties, |
| 159 | bool selected) |
| 160 | : wgpu::AdapterProperties(properties), adapterName(properties.name), selected(selected) { |
| 161 | } |
| 162 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 163 | AdapterTestParam::AdapterTestParam(const BackendTestConfig& config, |
| 164 | const TestAdapterProperties& adapterProperties) |
| 165 | : adapterProperties(adapterProperties), |
| 166 | forceEnabledWorkarounds(config.forceEnabledWorkarounds), |
| 167 | forceDisabledWorkarounds(config.forceDisabledWorkarounds) { |
| 168 | } |
| 169 | |
| 170 | std::ostream& operator<<(std::ostream& os, const AdapterTestParam& param) { |
Austin Eng | a9e39e1 | 2021-06-01 18:49:12 +0000 | [diff] [blame] | 171 | os << ParamName(param.adapterProperties.backendType) << " " |
| 172 | << param.adapterProperties.adapterName; |
Jiawei Shao | 8a3cc5c | 2020-05-21 00:24:16 +0000 | [diff] [blame] | 173 | |
| 174 | // In a Windows Remote Desktop session there are two adapters named "Microsoft Basic Render |
| 175 | // Driver" with different adapter types. We must differentiate them to avoid any tests using the |
| 176 | // same name. |
| 177 | if (param.adapterProperties.deviceID == 0x008C) { |
| 178 | std::string adapterType = AdapterTypeName(param.adapterProperties.adapterType); |
Austin Eng | a9e39e1 | 2021-06-01 18:49:12 +0000 | [diff] [blame] | 179 | os << " " << adapterType; |
Jiawei Shao | 8a3cc5c | 2020-05-21 00:24:16 +0000 | [diff] [blame] | 180 | } |
| 181 | |
Brian Ho | e25a3ae | 2019-08-27 01:44:29 +0000 | [diff] [blame] | 182 | for (const char* forceEnabledWorkaround : param.forceEnabledWorkarounds) { |
Austin Eng | a9e39e1 | 2021-06-01 18:49:12 +0000 | [diff] [blame] | 183 | os << "; e:" << forceEnabledWorkaround; |
Brian Ho | e25a3ae | 2019-08-27 01:44:29 +0000 | [diff] [blame] | 184 | } |
| 185 | for (const char* forceDisabledWorkaround : param.forceDisabledWorkarounds) { |
Austin Eng | a9e39e1 | 2021-06-01 18:49:12 +0000 | [diff] [blame] | 186 | os << "; d:" << forceDisabledWorkaround; |
Brian Ho | e25a3ae | 2019-08-27 01:44:29 +0000 | [diff] [blame] | 187 | } |
| 188 | return os; |
| 189 | } |
| 190 | |
Austin Eng | a9e39e1 | 2021-06-01 18:49:12 +0000 | [diff] [blame] | 191 | DawnTestBase::PrintToStringParamName::PrintToStringParamName(const char* test) : mTest(test) { |
| 192 | } |
| 193 | |
| 194 | std::string DawnTestBase::PrintToStringParamName::SanitizeParamName(std::string paramName, |
| 195 | size_t index) const { |
| 196 | // Sanitize the adapter name for GoogleTest |
| 197 | std::string sanitizedName = std::regex_replace(paramName, std::regex("[^a-zA-Z0-9]+"), "_"); |
| 198 | |
| 199 | // Strip trailing underscores, if any. |
| 200 | while (sanitizedName.back() == '_') { |
| 201 | sanitizedName.resize(sanitizedName.length() - 1); |
| 202 | } |
| 203 | |
| 204 | // We don't know the the test name at this point, but the format usually looks like |
| 205 | // this. |
| 206 | std::string prefix = mTest + ".TheTestNameUsuallyGoesHere/"; |
| 207 | std::string testFormat = prefix + sanitizedName; |
| 208 | if (testFormat.length() > 220) { |
| 209 | // The bots don't support test names longer than 256. Shorten the name and append a unique |
| 210 | // index if we're close. The failure log will still print the full param name. |
| 211 | std::string suffix = std::string("__") + std::to_string(index); |
| 212 | size_t targetLength = sanitizedName.length(); |
| 213 | targetLength -= testFormat.length() - 220; |
| 214 | targetLength -= suffix.length(); |
| 215 | sanitizedName.resize(targetLength); |
| 216 | sanitizedName = sanitizedName + suffix; |
| 217 | } |
| 218 | return sanitizedName; |
| 219 | } |
| 220 | |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 221 | // Implementation of DawnTestEnvironment |
| 222 | |
| 223 | void InitDawnEnd2EndTestEnvironment(int argc, char** argv) { |
| 224 | gTestEnv = new DawnTestEnvironment(argc, argv); |
| 225 | testing::AddGlobalTestEnvironment(gTestEnv); |
Corentin Wallez | 3499d3e | 2019-02-18 15:07:44 +0000 | [diff] [blame] | 226 | } |
| 227 | |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 228 | // static |
| 229 | void DawnTestEnvironment::SetEnvironment(DawnTestEnvironment* env) { |
| 230 | gTestEnv = env; |
| 231 | } |
| 232 | |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 233 | DawnTestEnvironment::DawnTestEnvironment(int argc, char** argv) { |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 234 | ParseArgs(argc, argv); |
| 235 | |
Brandon Jones | bdbf98a | 2021-02-04 19:32:12 +0000 | [diff] [blame] | 236 | if (mBackendValidationLevel != dawn_native::BackendValidationLevel::Disabled) { |
Bryan Bernhart | 6db3a24 | 2020-09-22 16:23:06 +0000 | [diff] [blame] | 237 | mPlatformDebugLogger = |
| 238 | std::unique_ptr<utils::PlatformDebugLogger>(utils::CreatePlatformDebugLogger()); |
| 239 | } |
| 240 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 241 | // Create a temporary instance to select available and preferred adapters. This is done before |
| 242 | // test instantiation so GetAvailableAdapterTestParamsForBackends can generate test |
| 243 | // parameterizations all selected adapters. We drop the instance at the end of this function |
| 244 | // because the Vulkan validation layers use static global mutexes which behave badly when |
| 245 | // Chromium's test launcher forks the test process. The instance will be recreated on test |
| 246 | // environment setup. |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 247 | std::unique_ptr<dawn_native::Instance> instance = CreateInstanceAndDiscoverAdapters(); |
| 248 | ASSERT(instance); |
| 249 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 250 | SelectPreferredAdapterProperties(instance.get()); |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 251 | PrintTestConfigurationAndAdapterInfo(instance.get()); |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 252 | } |
| 253 | |
Austin Eng | f580096 | 2020-08-14 21:02:12 +0000 | [diff] [blame] | 254 | DawnTestEnvironment::~DawnTestEnvironment() = default; |
| 255 | |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 256 | void DawnTestEnvironment::ParseArgs(int argc, char** argv) { |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 257 | size_t argLen = 0; // Set when parsing --arg=X arguments |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 258 | for (int i = 1; i < argc; ++i) { |
| 259 | if (strcmp("-w", argv[i]) == 0 || strcmp("--use-wire", argv[i]) == 0) { |
| 260 | mUseWire = true; |
| 261 | continue; |
| 262 | } |
| 263 | |
Jiawei Shao | 3fd2036 | 2021-05-19 08:31:13 +0000 | [diff] [blame] | 264 | if (strcmp("--run-suppressed-tests", argv[i]) == 0) { |
| 265 | mRunSuppressedTests = true; |
| 266 | continue; |
| 267 | } |
| 268 | |
Brandon Jones | bdbf98a | 2021-02-04 19:32:12 +0000 | [diff] [blame] | 269 | constexpr const char kEnableBackendValidationSwitch[] = "--enable-backend-validation"; |
| 270 | argLen = sizeof(kEnableBackendValidationSwitch) - 1; |
| 271 | if (strncmp(argv[i], kEnableBackendValidationSwitch, argLen) == 0) { |
| 272 | const char* level = argv[i] + argLen; |
| 273 | if (level[0] != '\0') { |
| 274 | if (strcmp(level, "=full") == 0) { |
| 275 | mBackendValidationLevel = dawn_native::BackendValidationLevel::Full; |
| 276 | } else if (strcmp(level, "=partial") == 0) { |
| 277 | mBackendValidationLevel = dawn_native::BackendValidationLevel::Partial; |
| 278 | } else if (strcmp(level, "=disabled") == 0) { |
| 279 | mBackendValidationLevel = dawn_native::BackendValidationLevel::Disabled; |
| 280 | } else { |
| 281 | dawn::ErrorLog() << "Invalid backend validation level" << level; |
| 282 | UNREACHABLE(); |
| 283 | } |
| 284 | } else { |
Bryan Bernhart | e688e52 | 2021-04-26 18:26:36 +0000 | [diff] [blame] | 285 | mBackendValidationLevel = dawn_native::BackendValidationLevel::Partial; |
Brandon Jones | bdbf98a | 2021-02-04 19:32:12 +0000 | [diff] [blame] | 286 | } |
Bryan Bernhart | 5ff4978 | 2021-03-22 17:18:46 +0000 | [diff] [blame] | 287 | continue; |
Li Hao | 0195dbf | 2019-05-15 06:06:26 +0000 | [diff] [blame] | 288 | } |
| 289 | |
Rafael Cintron | 4729b15 | 2019-06-21 02:09:05 +0000 | [diff] [blame] | 290 | if (strcmp("-c", argv[i]) == 0 || strcmp("--begin-capture-on-startup", argv[i]) == 0) { |
| 291 | mBeginCaptureOnStartup = true; |
| 292 | continue; |
| 293 | } |
| 294 | |
Ryan Harrison | acdc35d | 2021-04-14 14:55:07 +0000 | [diff] [blame] | 295 | if (mToggleParser.ParseEnabledToggles(argv[i])) { |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 296 | continue; |
| 297 | } |
| 298 | |
Ryan Harrison | acdc35d | 2021-04-14 14:55:07 +0000 | [diff] [blame] | 299 | if (mToggleParser.ParseDisabledToggles(argv[i])) { |
Austin Eng | 4d15609 | 2019-11-21 00:48:39 +0000 | [diff] [blame] | 300 | continue; |
| 301 | } |
| 302 | |
Austin Eng | 92a011a | 2019-10-17 19:00:32 +0000 | [diff] [blame] | 303 | constexpr const char kVendorIdFilterArg[] = "--adapter-vendor-id="; |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 304 | argLen = sizeof(kVendorIdFilterArg) - 1; |
| 305 | if (strncmp(argv[i], kVendorIdFilterArg, argLen) == 0) { |
| 306 | const char* vendorIdFilter = argv[i] + argLen; |
Austin Eng | 92a011a | 2019-10-17 19:00:32 +0000 | [diff] [blame] | 307 | if (vendorIdFilter[0] != '\0') { |
| 308 | mVendorIdFilter = strtoul(vendorIdFilter, nullptr, 16); |
Li, Hao | 35716c2 | 2019-07-08 03:25:54 +0000 | [diff] [blame] | 309 | // Set filter flag if vendor id is non-zero. |
| 310 | mHasVendorIdFilter = mVendorIdFilter != 0; |
| 311 | } |
| 312 | continue; |
| 313 | } |
| 314 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 315 | constexpr const char kExclusiveDeviceTypePreferenceArg[] = |
| 316 | "--exclusive-device-type-preference="; |
| 317 | argLen = sizeof(kExclusiveDeviceTypePreferenceArg) - 1; |
| 318 | if (strncmp(argv[i], kExclusiveDeviceTypePreferenceArg, argLen) == 0) { |
| 319 | const char* preference = argv[i] + argLen; |
| 320 | if (preference[0] != '\0') { |
| 321 | std::istringstream ss(preference); |
| 322 | std::string type; |
| 323 | while (std::getline(ss, type, ',')) { |
| 324 | if (strcmp(type.c_str(), "discrete") == 0) { |
| 325 | mDevicePreferences.push_back(dawn_native::DeviceType::DiscreteGPU); |
| 326 | } else if (strcmp(type.c_str(), "integrated") == 0) { |
| 327 | mDevicePreferences.push_back(dawn_native::DeviceType::IntegratedGPU); |
| 328 | } else if (strcmp(type.c_str(), "cpu") == 0) { |
| 329 | mDevicePreferences.push_back(dawn_native::DeviceType::CPU); |
| 330 | } else { |
| 331 | dawn::ErrorLog() << "Invalid device type preference: " << type; |
| 332 | UNREACHABLE(); |
| 333 | } |
| 334 | } |
| 335 | } |
Bryan Bernhart | 5ff4978 | 2021-03-22 17:18:46 +0000 | [diff] [blame] | 336 | continue; |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 337 | } |
| 338 | |
Austin Eng | cbc206e | 2019-12-10 23:32:48 +0000 | [diff] [blame] | 339 | constexpr const char kWireTraceDirArg[] = "--wire-trace-dir="; |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 340 | argLen = sizeof(kWireTraceDirArg) - 1; |
| 341 | if (strncmp(argv[i], kWireTraceDirArg, argLen) == 0) { |
Austin Eng | e58d5a3 | 2021-01-27 22:54:04 +0000 | [diff] [blame] | 342 | mWireTraceDir = argv[i] + argLen; |
Austin Eng | cbc206e | 2019-12-10 23:32:48 +0000 | [diff] [blame] | 343 | continue; |
| 344 | } |
| 345 | |
Stephen White | eb71aaf | 2021-02-17 17:07:08 +0000 | [diff] [blame] | 346 | constexpr const char kBackendArg[] = "--backend="; |
| 347 | argLen = sizeof(kBackendArg) - 1; |
| 348 | if (strncmp(argv[i], kBackendArg, argLen) == 0) { |
| 349 | const char* param = argv[i] + argLen; |
| 350 | if (strcmp("d3d12", param) == 0) { |
| 351 | mBackendTypeFilter = wgpu::BackendType::D3D12; |
| 352 | } else if (strcmp("metal", param) == 0) { |
| 353 | mBackendTypeFilter = wgpu::BackendType::Metal; |
| 354 | } else if (strcmp("null", param) == 0) { |
| 355 | mBackendTypeFilter = wgpu::BackendType::Null; |
| 356 | } else if (strcmp("opengl", param) == 0) { |
| 357 | mBackendTypeFilter = wgpu::BackendType::OpenGL; |
| 358 | } else if (strcmp("opengles", param) == 0) { |
| 359 | mBackendTypeFilter = wgpu::BackendType::OpenGLES; |
| 360 | } else if (strcmp("vulkan", param) == 0) { |
| 361 | mBackendTypeFilter = wgpu::BackendType::Vulkan; |
| 362 | } else { |
| 363 | dawn::ErrorLog() |
| 364 | << "Invalid backend \"" << param |
| 365 | << "\". Valid backends are: d3d12, metal, null, opengl, opengles, vulkan."; |
| 366 | UNREACHABLE(); |
| 367 | } |
| 368 | mHasBackendTypeFilter = true; |
| 369 | continue; |
| 370 | } |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 371 | if (strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) { |
Corentin Wallez | dc3317d | 2019-12-06 18:21:39 +0000 | [diff] [blame] | 372 | dawn::InfoLog() |
| 373 | << "\n\nUsage: " << argv[0] |
Brandon Jones | bdbf98a | 2021-02-04 19:32:12 +0000 | [diff] [blame] | 374 | << " [GTEST_FLAGS...] [-w] [-c]\n" |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 375 | " [--enable-toggles=toggles] [--disable-toggles=toggles]\n" |
Stephen White | eb71aaf | 2021-02-17 17:07:08 +0000 | [diff] [blame] | 376 | " [--backend=x]\n" |
Brandon Jones | bdbf98a | 2021-02-04 19:32:12 +0000 | [diff] [blame] | 377 | " [--adapter-vendor-id=x] " |
| 378 | "[--enable-backend-validation[=full,partial,disabled]]\n" |
| 379 | " [--exclusive-device-type-preference=integrated,cpu,discrete]\n\n" |
Corentin Wallez | dc3317d | 2019-12-06 18:21:39 +0000 | [diff] [blame] | 380 | " -w, --use-wire: Run the tests through the wire (defaults to no wire)\n" |
Corentin Wallez | dc3317d | 2019-12-06 18:21:39 +0000 | [diff] [blame] | 381 | " -c, --begin-capture-on-startup: Begin debug capture on startup " |
| 382 | "(defaults to no capture)\n" |
Bryan Bernhart | e688e52 | 2021-04-26 18:26:36 +0000 | [diff] [blame] | 383 | " --enable-backend-validation: Enables backend validation. Defaults to \n" |
| 384 | " 'partial' to enable only minimum backend validation. Set to 'full' to\n" |
| 385 | " enable all available backend validation with less performance overhead.\n" |
Brandon Jones | bdbf98a | 2021-02-04 19:32:12 +0000 | [diff] [blame] | 386 | " Set to 'disabled' to run with no validation (same as no flag).\n" |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 387 | " --enable-toggles: Comma-delimited list of Dawn toggles to enable.\n" |
Corentin Wallez | deb4057 | 2021-10-29 13:17:27 +0000 | [diff] [blame] | 388 | " ex.) skip_validation,disable_robustness,turn_off_vsync\n" |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 389 | " --disable-toggles: Comma-delimited list of Dawn toggles to disable\n" |
Corentin Wallez | dc3317d | 2019-12-06 18:21:39 +0000 | [diff] [blame] | 390 | " --adapter-vendor-id: Select adapter by vendor id to run end2end tests" |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 391 | "on multi-GPU systems \n" |
Stephen White | eb71aaf | 2021-02-17 17:07:08 +0000 | [diff] [blame] | 392 | " --backend: Select adapter by backend type. Valid backends are: d3d12, metal, " |
| 393 | "null, opengl, opengles, vulkan\n" |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 394 | " --exclusive-device-type-preference: Comma-delimited list of preferred device " |
| 395 | "types. For each backend, tests will run only on adapters that match the first " |
Jiawei Shao | 3fd2036 | 2021-05-19 08:31:13 +0000 | [diff] [blame] | 396 | "available device type\n" |
| 397 | " --run-suppressed-tests: Run all the tests that will be skipped by the macro " |
| 398 | "DAWN_SUPPRESS_TEST_IF()\n"; |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 399 | continue; |
| 400 | } |
Austin Eng | 7124cc4 | 2021-02-25 20:38:45 +0000 | [diff] [blame] | 401 | |
| 402 | // Skip over args that look like they're for Googletest. |
| 403 | constexpr const char kGtestArgPrefix[] = "--gtest_"; |
| 404 | if (strncmp(kGtestArgPrefix, argv[i], sizeof(kGtestArgPrefix) - 1) == 0) { |
| 405 | continue; |
| 406 | } |
| 407 | |
| 408 | dawn::WarningLog() << " Unused argument: " << argv[i]; |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 409 | } |
| 410 | } |
| 411 | |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 412 | std::unique_ptr<dawn_native::Instance> DawnTestEnvironment::CreateInstanceAndDiscoverAdapters() { |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 413 | auto instance = std::make_unique<dawn_native::Instance>(); |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 414 | instance->EnableBeginCaptureOnStartup(mBeginCaptureOnStartup); |
Brandon Jones | bdbf98a | 2021-02-04 19:32:12 +0000 | [diff] [blame] | 415 | instance->SetBackendValidationLevel(mBackendValidationLevel); |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 416 | instance->DiscoverDefaultAdapters(); |
| 417 | |
Stephen White | 21ce5d2 | 2021-05-17 18:04:48 +0000 | [diff] [blame] | 418 | #ifdef DAWN_ENABLE_BACKEND_DESKTOP_GL |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 419 | if (!glfwInit()) { |
| 420 | return instance; |
| 421 | } |
| 422 | glfwDefaultWindowHints(); |
| 423 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); |
| 424 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4); |
| 425 | glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); |
| 426 | glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); |
Stephen White | eb7108c | 2021-01-27 17:22:44 +0000 | [diff] [blame] | 427 | glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 428 | |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 429 | mOpenGLWindow = glfwCreateWindow(400, 400, "Dawn OpenGL test window", nullptr, nullptr); |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 430 | |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 431 | glfwMakeContextCurrent(mOpenGLWindow); |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 432 | dawn_native::opengl::AdapterDiscoveryOptions adapterOptions; |
| 433 | adapterOptions.getProc = reinterpret_cast<void* (*)(const char*)>(glfwGetProcAddress); |
| 434 | instance->DiscoverAdapters(&adapterOptions); |
Stephen White | 21ce5d2 | 2021-05-17 18:04:48 +0000 | [diff] [blame] | 435 | #endif // DAWN_ENABLE_BACKEND_DESKTOP_GL |
| 436 | |
| 437 | #ifdef DAWN_ENABLE_BACKEND_OPENGLES |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 438 | |
Austin Eng | 09c308c | 2021-11-16 23:37:15 +0000 | [diff] [blame] | 439 | ScopedEnvironmentVar angleDefaultPlatform; |
| 440 | if (GetEnvironmentVar("ANGLE_DEFAULT_PLATFORM").first.empty()) { |
| 441 | angleDefaultPlatform.Set("ANGLE_DEFAULT_PLATFORM", "swiftshader"); |
Stephen White | e7e42eb | 2021-02-08 21:30:44 +0000 | [diff] [blame] | 442 | } |
Austin Eng | 09c308c | 2021-11-16 23:37:15 +0000 | [diff] [blame] | 443 | |
Stephen White | 21ce5d2 | 2021-05-17 18:04:48 +0000 | [diff] [blame] | 444 | if (!glfwInit()) { |
| 445 | return instance; |
| 446 | } |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 447 | glfwDefaultWindowHints(); |
| 448 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); |
| 449 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); |
| 450 | glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); |
| 451 | glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API); |
Stephen White | eb7108c | 2021-01-27 17:22:44 +0000 | [diff] [blame] | 452 | glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 453 | |
| 454 | mOpenGLESWindow = glfwCreateWindow(400, 400, "Dawn OpenGLES test window", nullptr, nullptr); |
| 455 | |
| 456 | glfwMakeContextCurrent(mOpenGLESWindow); |
| 457 | dawn_native::opengl::AdapterDiscoveryOptionsES adapterOptionsES; |
Stephen White | 21ce5d2 | 2021-05-17 18:04:48 +0000 | [diff] [blame] | 458 | adapterOptionsES.getProc = reinterpret_cast<void* (*)(const char*)>(glfwGetProcAddress); |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 459 | instance->DiscoverAdapters(&adapterOptionsES); |
Stephen White | eb7108c | 2021-01-27 17:22:44 +0000 | [diff] [blame] | 460 | glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); |
Stephen White | 21ce5d2 | 2021-05-17 18:04:48 +0000 | [diff] [blame] | 461 | #endif // DAWN_ENABLE_BACKEND_OPENGLES |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 462 | |
| 463 | return instance; |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 464 | } |
| 465 | |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 466 | GLFWwindow* DawnTestEnvironment::GetOpenGLWindow() const { |
| 467 | return mOpenGLWindow; |
| 468 | } |
| 469 | |
| 470 | GLFWwindow* DawnTestEnvironment::GetOpenGLESWindow() const { |
| 471 | return mOpenGLESWindow; |
| 472 | } |
| 473 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 474 | void DawnTestEnvironment::SelectPreferredAdapterProperties(const dawn_native::Instance* instance) { |
| 475 | // Get the first available preferred device type. |
| 476 | dawn_native::DeviceType preferredDeviceType = static_cast<dawn_native::DeviceType>(-1); |
| 477 | bool hasDevicePreference = false; |
| 478 | for (dawn_native::DeviceType devicePreference : mDevicePreferences) { |
| 479 | for (const dawn_native::Adapter& adapter : instance->GetAdapters()) { |
| 480 | wgpu::AdapterProperties properties; |
| 481 | adapter.GetProperties(&properties); |
| 482 | |
| 483 | if (adapter.GetDeviceType() == devicePreference) { |
| 484 | preferredDeviceType = devicePreference; |
| 485 | hasDevicePreference = true; |
| 486 | break; |
| 487 | } |
| 488 | } |
| 489 | if (hasDevicePreference) { |
| 490 | break; |
| 491 | } |
| 492 | } |
| 493 | |
Jiawei Shao | e87a8c4 | 2020-11-05 08:38:46 +0000 | [diff] [blame] | 494 | std::set<std::pair<wgpu::BackendType, std::string>> adapterNameSet; |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 495 | for (const dawn_native::Adapter& adapter : instance->GetAdapters()) { |
| 496 | wgpu::AdapterProperties properties; |
| 497 | adapter.GetProperties(&properties); |
| 498 | |
Stephen White | eb71aaf | 2021-02-17 17:07:08 +0000 | [diff] [blame] | 499 | // All adapters are selected by default. |
| 500 | bool selected = true; |
| 501 | // The adapter is deselected if: |
| 502 | if (mHasBackendTypeFilter) { |
| 503 | // It doesn't match the backend type, if present. |
| 504 | selected &= properties.backendType == mBackendTypeFilter; |
| 505 | } |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 506 | if (mHasVendorIdFilter) { |
Stephen White | eb71aaf | 2021-02-17 17:07:08 +0000 | [diff] [blame] | 507 | // It doesn't match the vendor id, if present. |
| 508 | selected &= mVendorIdFilter == properties.vendorID; |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 509 | |
| 510 | if (!mDevicePreferences.empty()) { |
| 511 | dawn::WarningLog() << "Vendor ID filter provided. Ignoring device type preference."; |
| 512 | } |
Stephen White | eb71aaf | 2021-02-17 17:07:08 +0000 | [diff] [blame] | 513 | } |
| 514 | if (hasDevicePreference) { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 515 | // There is a device preference and: |
Stephen White | eb71aaf | 2021-02-17 17:07:08 +0000 | [diff] [blame] | 516 | selected &= |
| 517 | // The device type doesn't match the first available preferred type for that |
| 518 | // backend, if present. |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 519 | (adapter.GetDeviceType() == preferredDeviceType) || |
| 520 | // Always select Unknown OpenGL adapters if we don't want a CPU adapter. |
| 521 | // OpenGL will usually be unknown because we can't query the device type. |
| 522 | // If we ever have Swiftshader GL (unlikely), we could set the DeviceType properly. |
| 523 | (preferredDeviceType != dawn_native::DeviceType::CPU && |
| 524 | adapter.GetDeviceType() == dawn_native::DeviceType::Unknown && |
Stephen White | 040f140 | 2021-02-03 17:36:29 +0000 | [diff] [blame] | 525 | (properties.backendType == wgpu::BackendType::OpenGL || |
| 526 | properties.backendType == wgpu::BackendType::OpenGLES)) || |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 527 | // Always select the Null backend. There are few tests on this backend, and they run |
| 528 | // quickly. This is temporary as to not lose coverage. We can group it with |
| 529 | // Swiftshader as a CPU adapter when we have Swiftshader tests. |
| 530 | (properties.backendType == wgpu::BackendType::Null); |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 531 | } |
| 532 | |
Jiawei Shao | e87a8c4 | 2020-11-05 08:38:46 +0000 | [diff] [blame] | 533 | // In Windows Remote Desktop sessions we may be able to discover multiple adapters that |
| 534 | // have the same name and backend type. We will just choose one adapter from them in our |
| 535 | // tests. |
| 536 | const auto adapterTypeAndName = |
| 537 | std::make_pair(properties.backendType, std::string(properties.name)); |
| 538 | if (adapterNameSet.find(adapterTypeAndName) == adapterNameSet.end()) { |
| 539 | adapterNameSet.insert(adapterTypeAndName); |
| 540 | mAdapterProperties.emplace_back(properties, selected); |
| 541 | } |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 542 | } |
| 543 | } |
| 544 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 545 | std::vector<AdapterTestParam> DawnTestEnvironment::GetAvailableAdapterTestParamsForBackends( |
| 546 | const BackendTestConfig* params, |
| 547 | size_t numParams) { |
| 548 | std::vector<AdapterTestParam> testParams; |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 549 | for (size_t i = 0; i < numParams; ++i) { |
| 550 | for (const auto& adapterProperties : mAdapterProperties) { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 551 | if (params[i].backendType == adapterProperties.backendType && |
| 552 | adapterProperties.selected) { |
| 553 | testParams.push_back(AdapterTestParam(params[i], adapterProperties)); |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 554 | } |
| 555 | } |
| 556 | } |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 557 | return testParams; |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 558 | } |
| 559 | |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 560 | void DawnTestEnvironment::PrintTestConfigurationAndAdapterInfo( |
| 561 | dawn_native::Instance* instance) const { |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 562 | dawn::LogMessage log = dawn::InfoLog(); |
| 563 | log << "Testing configuration\n" |
| 564 | "---------------------\n" |
| 565 | "UseWire: " |
| 566 | << (mUseWire ? "true" : "false") |
| 567 | << "\n" |
Jiawei Shao | 3fd2036 | 2021-05-19 08:31:13 +0000 | [diff] [blame] | 568 | "Run suppressed tests: " |
| 569 | << (mRunSuppressedTests ? "true" : "false") |
| 570 | << "\n" |
Brandon Jones | bdbf98a | 2021-02-04 19:32:12 +0000 | [diff] [blame] | 571 | "BackendValidation: "; |
| 572 | |
| 573 | switch (mBackendValidationLevel) { |
| 574 | case dawn_native::BackendValidationLevel::Full: |
| 575 | log << "full"; |
| 576 | break; |
| 577 | case dawn_native::BackendValidationLevel::Partial: |
| 578 | log << "partial"; |
| 579 | break; |
| 580 | case dawn_native::BackendValidationLevel::Disabled: |
| 581 | log << "disabled"; |
| 582 | break; |
| 583 | default: |
| 584 | UNREACHABLE(); |
| 585 | } |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 586 | |
| 587 | if (GetEnabledToggles().size() > 0) { |
| 588 | log << "\n" |
| 589 | "Enabled Toggles\n"; |
| 590 | for (const std::string& toggle : GetEnabledToggles()) { |
| 591 | const dawn_native::ToggleInfo* info = instance->GetToggleInfo(toggle.c_str()); |
| 592 | ASSERT(info != nullptr); |
| 593 | log << " - " << info->name << ": " << info->description << "\n"; |
| 594 | } |
| 595 | } |
| 596 | |
| 597 | if (GetDisabledToggles().size() > 0) { |
| 598 | log << "\n" |
| 599 | "Disabled Toggles\n"; |
| 600 | for (const std::string& toggle : GetDisabledToggles()) { |
| 601 | const dawn_native::ToggleInfo* info = instance->GetToggleInfo(toggle.c_str()); |
| 602 | ASSERT(info != nullptr); |
| 603 | log << " - " << info->name << ": " << info->description << "\n"; |
| 604 | } |
| 605 | } |
| 606 | |
| 607 | log << "\n" |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 608 | "BeginCaptureOnStartup: " |
| 609 | << (mBeginCaptureOnStartup ? "true" : "false") |
| 610 | << "\n" |
| 611 | "\n" |
| 612 | << "System adapters: \n"; |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 613 | |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 614 | for (const TestAdapterProperties& properties : mAdapterProperties) { |
Corentin Wallez | fda0617 | 2019-02-21 17:36:11 +0000 | [diff] [blame] | 615 | std::ostringstream vendorId; |
| 616 | std::ostringstream deviceId; |
| 617 | vendorId << std::setfill('0') << std::uppercase << std::internal << std::hex << std::setw(4) |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 618 | << properties.vendorID; |
Corentin Wallez | fda0617 | 2019-02-21 17:36:11 +0000 | [diff] [blame] | 619 | deviceId << std::setfill('0') << std::uppercase << std::internal << std::hex << std::setw(4) |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 620 | << properties.deviceID; |
Corentin Wallez | fda0617 | 2019-02-21 17:36:11 +0000 | [diff] [blame] | 621 | |
Corentin Wallez | 95586ff | 2019-12-05 11:13:01 +0000 | [diff] [blame] | 622 | // Preparing for outputting hex numbers |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 623 | log << std::showbase << std::hex << std::setfill('0') << std::setw(4) |
Corentin Wallez | 95586ff | 2019-12-05 11:13:01 +0000 | [diff] [blame] | 624 | |
Corentin Wallez | 73b7022 | 2020-10-14 13:33:15 +0000 | [diff] [blame] | 625 | << " - \"" << properties.adapterName << "\" - \"" << properties.driverDescription |
| 626 | << "\"\n" |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 627 | << " type: " << AdapterTypeName(properties.adapterType) |
| 628 | << ", backend: " << ParamName(properties.backendType) << "\n" |
| 629 | << " vendorId: 0x" << vendorId.str() << ", deviceId: 0x" << deviceId.str() |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 630 | << (properties.selected ? " [Selected]" : "") << "\n"; |
Corentin Wallez | fda0617 | 2019-02-21 17:36:11 +0000 | [diff] [blame] | 631 | } |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 632 | } |
| 633 | |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 634 | void DawnTestEnvironment::SetUp() { |
| 635 | mInstance = CreateInstanceAndDiscoverAdapters(); |
| 636 | ASSERT(mInstance); |
Austin Eng | 5133221 | 2020-05-15 16:04:32 +0000 | [diff] [blame] | 637 | } |
| 638 | |
Jiajie Hu | 9e5b9ed | 2019-11-20 09:45:41 +0000 | [diff] [blame] | 639 | void DawnTestEnvironment::TearDown() { |
| 640 | // When Vulkan validation layers are enabled, it's unsafe to call Vulkan APIs in the destructor |
| 641 | // of a static/global variable, so the instance must be manually released beforehand. |
| 642 | mInstance.reset(); |
| 643 | } |
| 644 | |
Corentin Wallez | 0ee9859 | 2019-05-01 12:57:27 +0000 | [diff] [blame] | 645 | bool DawnTestEnvironment::UsesWire() const { |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 646 | return mUseWire; |
| 647 | } |
| 648 | |
Jiawei Shao | 3fd2036 | 2021-05-19 08:31:13 +0000 | [diff] [blame] | 649 | bool DawnTestEnvironment::RunSuppressedTests() const { |
| 650 | return mRunSuppressedTests; |
| 651 | } |
| 652 | |
Brandon Jones | bdbf98a | 2021-02-04 19:32:12 +0000 | [diff] [blame] | 653 | dawn_native::BackendValidationLevel DawnTestEnvironment::GetBackendValidationLevel() const { |
| 654 | return mBackendValidationLevel; |
Li, Hao | 6fa398e | 2019-06-25 00:49:56 +0000 | [diff] [blame] | 655 | } |
| 656 | |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 657 | dawn_native::Instance* DawnTestEnvironment::GetInstance() const { |
| 658 | return mInstance.get(); |
| 659 | } |
| 660 | |
Li, Hao | 35716c2 | 2019-07-08 03:25:54 +0000 | [diff] [blame] | 661 | bool DawnTestEnvironment::HasVendorIdFilter() const { |
| 662 | return mHasVendorIdFilter; |
| 663 | } |
| 664 | |
| 665 | uint32_t DawnTestEnvironment::GetVendorIdFilter() const { |
| 666 | return mVendorIdFilter; |
| 667 | } |
| 668 | |
Stephen White | eb71aaf | 2021-02-17 17:07:08 +0000 | [diff] [blame] | 669 | bool DawnTestEnvironment::HasBackendTypeFilter() const { |
| 670 | return mHasBackendTypeFilter; |
| 671 | } |
| 672 | |
| 673 | wgpu::BackendType DawnTestEnvironment::GetBackendTypeFilter() const { |
| 674 | return mBackendTypeFilter; |
| 675 | } |
| 676 | |
Austin Eng | cbc206e | 2019-12-10 23:32:48 +0000 | [diff] [blame] | 677 | const char* DawnTestEnvironment::GetWireTraceDir() const { |
| 678 | if (mWireTraceDir.length() == 0) { |
| 679 | return nullptr; |
| 680 | } |
| 681 | return mWireTraceDir.c_str(); |
| 682 | } |
| 683 | |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 684 | const std::vector<std::string>& DawnTestEnvironment::GetEnabledToggles() const { |
Ryan Harrison | acdc35d | 2021-04-14 14:55:07 +0000 | [diff] [blame] | 685 | return mToggleParser.GetEnabledToggles(); |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 686 | } |
| 687 | |
| 688 | const std::vector<std::string>& DawnTestEnvironment::GetDisabledToggles() const { |
Ryan Harrison | acdc35d | 2021-04-14 14:55:07 +0000 | [diff] [blame] | 689 | return mToggleParser.GetDisabledToggles(); |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 690 | } |
| 691 | |
Corentin Wallez | 0b2f552 | 2019-02-21 16:29:12 +0000 | [diff] [blame] | 692 | // Implementation of DawnTest |
| 693 | |
Austin Eng | e58d5a3 | 2021-01-27 22:54:04 +0000 | [diff] [blame] | 694 | DawnTestBase::DawnTestBase(const AdapterTestParam& param) |
| 695 | : mParam(param), |
| 696 | mWireHelper(utils::CreateWireHelper(gTestEnv->UsesWire(), gTestEnv->GetWireTraceDir())) { |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 697 | } |
Corentin Wallez | cca9c69 | 2018-09-06 15:26:48 +0200 | [diff] [blame] | 698 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 699 | DawnTestBase::~DawnTestBase() { |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 700 | // We need to destroy child objects before the Device |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 701 | mReadbackSlots.clear(); |
Corentin Wallez | cab352c | 2019-10-28 13:27:36 +0000 | [diff] [blame] | 702 | queue = wgpu::Queue(); |
| 703 | device = wgpu::Device(); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 704 | |
Brandon Jones | 0a295c0 | 2021-02-24 22:09:30 +0000 | [diff] [blame] | 705 | // D3D12's GPU-based validation will accumulate objects over time if the backend device is not |
| 706 | // destroyed and recreated, so we reset it here. |
| 707 | if (IsD3D12() && IsBackendValidationEnabled()) { |
| 708 | mBackendAdapter.ResetInternalDeviceForTesting(); |
| 709 | } |
Austin Eng | e58d5a3 | 2021-01-27 22:54:04 +0000 | [diff] [blame] | 710 | mWireHelper.reset(); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 711 | } |
| 712 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 713 | bool DawnTestBase::IsD3D12() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 714 | return mParam.adapterProperties.backendType == wgpu::BackendType::D3D12; |
Austin Eng | 77a2998 | 2017-07-12 20:36:36 -0400 | [diff] [blame] | 715 | } |
| 716 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 717 | bool DawnTestBase::IsMetal() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 718 | return mParam.adapterProperties.backendType == wgpu::BackendType::Metal; |
Corentin Wallez | e1f16a2 | 2017-07-18 10:31:50 -0400 | [diff] [blame] | 719 | } |
| 720 | |
Corentin Wallez | 11652ff | 2020-03-20 17:07:20 +0000 | [diff] [blame] | 721 | bool DawnTestBase::IsNull() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 722 | return mParam.adapterProperties.backendType == wgpu::BackendType::Null; |
Corentin Wallez | 11652ff | 2020-03-20 17:07:20 +0000 | [diff] [blame] | 723 | } |
| 724 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 725 | bool DawnTestBase::IsOpenGL() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 726 | return mParam.adapterProperties.backendType == wgpu::BackendType::OpenGL; |
Corentin Wallez | e1f16a2 | 2017-07-18 10:31:50 -0400 | [diff] [blame] | 727 | } |
| 728 | |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 729 | bool DawnTestBase::IsOpenGLES() const { |
| 730 | return mParam.adapterProperties.backendType == wgpu::BackendType::OpenGLES; |
| 731 | } |
| 732 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 733 | bool DawnTestBase::IsVulkan() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 734 | return mParam.adapterProperties.backendType == wgpu::BackendType::Vulkan; |
Corentin Wallez | e1f16a2 | 2017-07-18 10:31:50 -0400 | [diff] [blame] | 735 | } |
| 736 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 737 | bool DawnTestBase::IsAMD() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 738 | return gpu_info::IsAMD(mParam.adapterProperties.vendorID); |
Jiawei Shao | 58809d4 | 2018-09-19 00:32:52 +0000 | [diff] [blame] | 739 | } |
| 740 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 741 | bool DawnTestBase::IsARM() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 742 | return gpu_info::IsARM(mParam.adapterProperties.vendorID); |
Jiawei Shao | 58809d4 | 2018-09-19 00:32:52 +0000 | [diff] [blame] | 743 | } |
| 744 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 745 | bool DawnTestBase::IsImgTec() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 746 | return gpu_info::IsImgTec(mParam.adapterProperties.vendorID); |
Jiawei Shao | 58809d4 | 2018-09-19 00:32:52 +0000 | [diff] [blame] | 747 | } |
| 748 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 749 | bool DawnTestBase::IsIntel() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 750 | return gpu_info::IsIntel(mParam.adapterProperties.vendorID); |
Jiawei Shao | 58809d4 | 2018-09-19 00:32:52 +0000 | [diff] [blame] | 751 | } |
| 752 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 753 | bool DawnTestBase::IsNvidia() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 754 | return gpu_info::IsNvidia(mParam.adapterProperties.vendorID); |
Jiawei Shao | 58809d4 | 2018-09-19 00:32:52 +0000 | [diff] [blame] | 755 | } |
| 756 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 757 | bool DawnTestBase::IsQualcomm() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 758 | return gpu_info::IsQualcomm(mParam.adapterProperties.vendorID); |
Jiawei Shao | 58809d4 | 2018-09-19 00:32:52 +0000 | [diff] [blame] | 759 | } |
| 760 | |
Corentin Wallez | d56b69f | 2020-04-09 08:16:30 +0000 | [diff] [blame] | 761 | bool DawnTestBase::IsSwiftshader() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 762 | return gpu_info::IsSwiftshader(mParam.adapterProperties.vendorID, |
| 763 | mParam.adapterProperties.deviceID); |
Corentin Wallez | d56b69f | 2020-04-09 08:16:30 +0000 | [diff] [blame] | 764 | } |
| 765 | |
Stephen White | f09a670 | 2021-01-18 17:47:07 +0000 | [diff] [blame] | 766 | bool DawnTestBase::IsANGLE() const { |
| 767 | return !mParam.adapterProperties.adapterName.find("ANGLE"); |
| 768 | } |
| 769 | |
Bryan Bernhart | 8c255ac | 2020-07-10 22:58:48 +0000 | [diff] [blame] | 770 | bool DawnTestBase::IsWARP() const { |
| 771 | return gpu_info::IsWARP(mParam.adapterProperties.vendorID, mParam.adapterProperties.deviceID); |
| 772 | } |
| 773 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 774 | bool DawnTestBase::IsWindows() const { |
Jiawei Shao | 58809d4 | 2018-09-19 00:32:52 +0000 | [diff] [blame] | 775 | #ifdef DAWN_PLATFORM_WINDOWS |
| 776 | return true; |
| 777 | #else |
| 778 | return false; |
| 779 | #endif |
| 780 | } |
| 781 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 782 | bool DawnTestBase::IsLinux() const { |
Jiawei Shao | 58809d4 | 2018-09-19 00:32:52 +0000 | [diff] [blame] | 783 | #ifdef DAWN_PLATFORM_LINUX |
| 784 | return true; |
| 785 | #else |
| 786 | return false; |
| 787 | #endif |
| 788 | } |
| 789 | |
Austin Eng | e50f8c6 | 2021-07-21 18:34:19 +0000 | [diff] [blame] | 790 | bool DawnTestBase::IsMacOS(int32_t majorVersion, int32_t minorVersion) const { |
James Price | 565863e | 2021-08-05 20:35:19 +0000 | [diff] [blame] | 791 | #ifdef DAWN_PLATFORM_MACOS |
Austin Eng | e50f8c6 | 2021-07-21 18:34:19 +0000 | [diff] [blame] | 792 | if (majorVersion == -1 && minorVersion == -1) { |
| 793 | return true; |
| 794 | } |
| 795 | int32_t majorVersionOut, minorVersionOut = 0; |
| 796 | GetMacOSVersion(&majorVersionOut, &minorVersionOut); |
| 797 | return (majorVersion != -1 && majorVersion == majorVersionOut) && |
| 798 | (minorVersion != -1 && minorVersion == minorVersionOut); |
Jiawei Shao | 58809d4 | 2018-09-19 00:32:52 +0000 | [diff] [blame] | 799 | #else |
| 800 | return false; |
| 801 | #endif |
| 802 | } |
| 803 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 804 | bool DawnTestBase::UsesWire() const { |
Corentin Wallez | 0ee9859 | 2019-05-01 12:57:27 +0000 | [diff] [blame] | 805 | return gTestEnv->UsesWire(); |
| 806 | } |
| 807 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 808 | bool DawnTestBase::IsBackendValidationEnabled() const { |
Brandon Jones | bdbf98a | 2021-02-04 19:32:12 +0000 | [diff] [blame] | 809 | return gTestEnv->GetBackendValidationLevel() != dawn_native::BackendValidationLevel::Disabled; |
Li, Hao | 6fa398e | 2019-06-25 00:49:56 +0000 | [diff] [blame] | 810 | } |
| 811 | |
Jiawei Shao | 3fd2036 | 2021-05-19 08:31:13 +0000 | [diff] [blame] | 812 | bool DawnTestBase::RunSuppressedTests() const { |
| 813 | return gTestEnv->RunSuppressedTests(); |
| 814 | } |
| 815 | |
Ben Clayton | cd417bc | 2021-06-16 20:18:08 +0000 | [diff] [blame] | 816 | bool DawnTestBase::IsDXC() const { |
| 817 | return HasToggleEnabled("use_dxc"); |
| 818 | } |
| 819 | |
Austin Eng | 0e9e5ee | 2020-06-19 17:35:33 +0000 | [diff] [blame] | 820 | bool DawnTestBase::IsAsan() const { |
| 821 | #if defined(ADDRESS_SANITIZER) |
| 822 | return true; |
| 823 | #else |
| 824 | return false; |
| 825 | #endif |
| 826 | } |
| 827 | |
Enrico Galli | 2b6b0f4 | 2020-11-05 18:52:49 +0000 | [diff] [blame] | 828 | bool DawnTestBase::HasToggleEnabled(const char* toggle) const { |
Austin Eng | f731a81 | 2020-12-04 02:07:20 +0000 | [diff] [blame] | 829 | auto toggles = dawn_native::GetTogglesUsed(backendDevice); |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 830 | return std::find_if(toggles.begin(), toggles.end(), [toggle](const char* name) { |
| 831 | return strcmp(toggle, name) == 0; |
| 832 | }) != toggles.end(); |
Enrico Galli | 2b6b0f4 | 2020-11-05 18:52:49 +0000 | [diff] [blame] | 833 | } |
| 834 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 835 | bool DawnTestBase::HasVendorIdFilter() const { |
Li, Hao | 35716c2 | 2019-07-08 03:25:54 +0000 | [diff] [blame] | 836 | return gTestEnv->HasVendorIdFilter(); |
| 837 | } |
| 838 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 839 | uint32_t DawnTestBase::GetVendorIdFilter() const { |
Li, Hao | 35716c2 | 2019-07-08 03:25:54 +0000 | [diff] [blame] | 840 | return gTestEnv->GetVendorIdFilter(); |
| 841 | } |
| 842 | |
Stephen White | eb71aaf | 2021-02-17 17:07:08 +0000 | [diff] [blame] | 843 | bool DawnTestBase::HasBackendTypeFilter() const { |
| 844 | return gTestEnv->HasBackendTypeFilter(); |
| 845 | } |
| 846 | |
| 847 | wgpu::BackendType DawnTestBase::GetBackendTypeFilter() const { |
| 848 | return gTestEnv->GetBackendTypeFilter(); |
| 849 | } |
| 850 | |
Corentin Wallez | 11652ff | 2020-03-20 17:07:20 +0000 | [diff] [blame] | 851 | wgpu::Instance DawnTestBase::GetInstance() const { |
| 852 | return gTestEnv->GetInstance()->Get(); |
| 853 | } |
| 854 | |
| 855 | dawn_native::Adapter DawnTestBase::GetAdapter() const { |
| 856 | return mBackendAdapter; |
| 857 | } |
| 858 | |
François Beaufort | 3f689a4 | 2021-10-04 11:30:02 +0000 | [diff] [blame] | 859 | std::vector<const char*> DawnTestBase::GetRequiredFeatures() { |
Jiawei Shao | 574b951 | 2019-08-02 00:06:38 +0000 | [diff] [blame] | 860 | return {}; |
| 861 | } |
| 862 | |
Austin Eng | 26ae0ea | 2021-10-19 16:06:21 +0000 | [diff] [blame] | 863 | wgpu::RequiredLimits DawnTestBase::GetRequiredLimits(const wgpu::SupportedLimits&) { |
| 864 | return {}; |
| 865 | } |
| 866 | |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 867 | const wgpu::AdapterProperties& DawnTestBase::GetAdapterProperties() const { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 868 | return mParam.adapterProperties; |
Corentin Wallez | f12c9db | 2020-01-10 13:28:18 +0000 | [diff] [blame] | 869 | } |
| 870 | |
Austin Eng | 91851e2 | 2021-10-13 18:57:18 +0000 | [diff] [blame] | 871 | wgpu::SupportedLimits DawnTestBase::GetSupportedLimits() { |
| 872 | WGPUSupportedLimits supportedLimits; |
| 873 | supportedLimits.nextInChain = nullptr; |
| 874 | dawn_native::GetProcs().deviceGetLimits(backendDevice, &supportedLimits); |
| 875 | return *reinterpret_cast<wgpu::SupportedLimits*>(&supportedLimits); |
| 876 | } |
| 877 | |
François Beaufort | 3f689a4 | 2021-10-04 11:30:02 +0000 | [diff] [blame] | 878 | bool DawnTestBase::SupportsFeatures(const std::vector<const char*>& features) { |
Jiawei Shao | 574b951 | 2019-08-02 00:06:38 +0000 | [diff] [blame] | 879 | ASSERT(mBackendAdapter); |
François Beaufort | 3f689a4 | 2021-10-04 11:30:02 +0000 | [diff] [blame] | 880 | std::set<std::string> supportedFeaturesSet; |
| 881 | for (const char* supportedFeatureName : mBackendAdapter.GetSupportedFeatures()) { |
| 882 | supportedFeaturesSet.insert(supportedFeatureName); |
Jiawei Shao | 574b951 | 2019-08-02 00:06:38 +0000 | [diff] [blame] | 883 | } |
| 884 | |
François Beaufort | 3f689a4 | 2021-10-04 11:30:02 +0000 | [diff] [blame] | 885 | for (const char* featureName : features) { |
| 886 | if (supportedFeaturesSet.find(featureName) == supportedFeaturesSet.end()) { |
Jiawei Shao | 574b951 | 2019-08-02 00:06:38 +0000 | [diff] [blame] | 887 | return false; |
| 888 | } |
| 889 | } |
| 890 | |
| 891 | return true; |
| 892 | } |
| 893 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 894 | void DawnTestBase::SetUp() { |
Corentin Wallez | bb5696b | 2019-02-12 15:48:15 +0000 | [diff] [blame] | 895 | { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 896 | // Find the adapter that exactly matches our adapter properties. |
| 897 | const auto& adapters = gTestEnv->GetInstance()->GetAdapters(); |
| 898 | const auto& it = std::find_if( |
| 899 | adapters.begin(), adapters.end(), [&](const dawn_native::Adapter& adapter) { |
| 900 | wgpu::AdapterProperties properties; |
| 901 | adapter.GetProperties(&properties); |
Corentin Wallez | af5d186 | 2019-02-27 10:09:46 +0000 | [diff] [blame] | 902 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 903 | return (mParam.adapterProperties.selected && |
| 904 | properties.deviceID == mParam.adapterProperties.deviceID && |
| 905 | properties.vendorID == mParam.adapterProperties.vendorID && |
| 906 | properties.adapterType == mParam.adapterProperties.adapterType && |
| 907 | properties.backendType == mParam.adapterProperties.backendType && |
| 908 | strcmp(properties.name, mParam.adapterProperties.adapterName.c_str()) == 0); |
| 909 | }); |
| 910 | ASSERT(it != adapters.end()); |
| 911 | mBackendAdapter = *it; |
Corentin Wallez | bb5696b | 2019-02-12 15:48:15 +0000 | [diff] [blame] | 912 | } |
| 913 | |
Bryan Bernhart | 41b3f9c | 2020-11-20 20:38:37 +0000 | [diff] [blame] | 914 | // Setup the per-test platform. Tests can provide one by overloading CreateTestPlatform. |
| 915 | mTestPlatform = CreateTestPlatform(); |
| 916 | gTestEnv->GetInstance()->SetPlatform(mTestPlatform.get()); |
| 917 | |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 918 | // Create the device from the adapter |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 919 | for (const char* forceEnabledWorkaround : mParam.forceEnabledWorkarounds) { |
Natasha Lee | 97f08fa | 2019-05-11 00:21:50 +0000 | [diff] [blame] | 920 | ASSERT(gTestEnv->GetInstance()->GetToggleInfo(forceEnabledWorkaround) != nullptr); |
Jiawei Shao | 15d4c2e | 2019-04-26 07:52:57 +0000 | [diff] [blame] | 921 | } |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 922 | for (const char* forceDisabledWorkaround : mParam.forceDisabledWorkarounds) { |
Natasha Lee | 28232ce | 2019-06-11 18:11:05 +0000 | [diff] [blame] | 923 | ASSERT(gTestEnv->GetInstance()->GetToggleInfo(forceDisabledWorkaround) != nullptr); |
| 924 | } |
Austin Eng | 3482a80 | 2021-11-23 18:03:16 +0000 | [diff] [blame] | 925 | dawn_native::DawnDeviceDescriptor deviceDescriptor = {}; |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 926 | deviceDescriptor.forceEnabledToggles = mParam.forceEnabledWorkarounds; |
| 927 | deviceDescriptor.forceDisabledToggles = mParam.forceDisabledWorkarounds; |
François Beaufort | 3f689a4 | 2021-10-04 11:30:02 +0000 | [diff] [blame] | 928 | deviceDescriptor.requiredFeatures = GetRequiredFeatures(); |
Austin Eng | 4d15609 | 2019-11-21 00:48:39 +0000 | [diff] [blame] | 929 | |
Austin Eng | 26ae0ea | 2021-10-19 16:06:21 +0000 | [diff] [blame] | 930 | wgpu::SupportedLimits supportedLimits; |
| 931 | mBackendAdapter.GetLimits(reinterpret_cast<WGPUSupportedLimits*>(&supportedLimits)); |
| 932 | wgpu::RequiredLimits requiredLimits = GetRequiredLimits(supportedLimits); |
| 933 | deviceDescriptor.requiredLimits = reinterpret_cast<WGPURequiredLimits*>(&requiredLimits); |
| 934 | |
Corentin Wallez | 07987ed | 2021-02-01 16:22:08 +0000 | [diff] [blame] | 935 | // Disabled disallowing unsafe APIs so we can test them. |
| 936 | deviceDescriptor.forceDisabledToggles.push_back("disallow_unsafe_apis"); |
| 937 | |
Austin Eng | b38a9c3 | 2020-11-14 01:09:23 +0000 | [diff] [blame] | 938 | for (const std::string& toggle : gTestEnv->GetEnabledToggles()) { |
| 939 | const dawn_native::ToggleInfo* info = |
| 940 | gTestEnv->GetInstance()->GetToggleInfo(toggle.c_str()); |
| 941 | ASSERT(info != nullptr); |
| 942 | deviceDescriptor.forceEnabledToggles.push_back(info->name); |
| 943 | } |
| 944 | |
| 945 | for (const std::string& toggle : gTestEnv->GetDisabledToggles()) { |
| 946 | const dawn_native::ToggleInfo* info = |
| 947 | gTestEnv->GetInstance()->GetToggleInfo(toggle.c_str()); |
| 948 | ASSERT(info != nullptr); |
| 949 | deviceDescriptor.forceDisabledToggles.push_back(info->name); |
Austin Eng | 4d15609 | 2019-11-21 00:48:39 +0000 | [diff] [blame] | 950 | } |
| 951 | |
Austin Eng | e58d5a3 | 2021-01-27 22:54:04 +0000 | [diff] [blame] | 952 | std::tie(device, backendDevice) = |
| 953 | mWireHelper->RegisterDevice(mBackendAdapter.CreateDevice(&deviceDescriptor)); |
Jiawei Shao | 574b951 | 2019-08-02 00:06:38 +0000 | [diff] [blame] | 954 | ASSERT_NE(nullptr, backendDevice); |
Jiawei Shao | 15d4c2e | 2019-04-26 07:52:57 +0000 | [diff] [blame] | 955 | |
Austin Eng | e58d5a3 | 2021-01-27 22:54:04 +0000 | [diff] [blame] | 956 | std::string traceName = |
| 957 | std::string(::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name()) + |
| 958 | "_" + ::testing::UnitTest::GetInstance()->current_test_info()->name(); |
| 959 | mWireHelper->BeginWireTrace(traceName.c_str()); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 960 | |
Corentin Wallez | 6d315da | 2021-02-04 15:33:42 +0000 | [diff] [blame] | 961 | queue = device.GetQueue(); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 962 | |
Austin Eng | 45ea7e6 | 2019-08-27 21:43:56 +0000 | [diff] [blame] | 963 | device.SetUncapturedErrorCallback(OnDeviceError, this); |
Natasha Lee | 0ecc48e | 2020-01-15 19:02:13 +0000 | [diff] [blame] | 964 | device.SetDeviceLostCallback(OnDeviceLost, this); |
Stephen White | 21ce5d2 | 2021-05-17 18:04:48 +0000 | [diff] [blame] | 965 | #if defined(DAWN_ENABLE_BACKEND_DESKTOP_GL) |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 966 | if (IsOpenGL()) { |
| 967 | glfwMakeContextCurrent(gTestEnv->GetOpenGLWindow()); |
Stephen White | 21ce5d2 | 2021-05-17 18:04:48 +0000 | [diff] [blame] | 968 | } |
| 969 | #endif // defined(DAWN_ENABLE_BACKEND_DESKTOP_GL) |
| 970 | #if defined(DAWN_ENABLE_BACKEND_OPENGLES) |
| 971 | if (IsOpenGLES()) { |
Stephen White | d45ab07 | 2020-11-25 16:45:04 +0000 | [diff] [blame] | 972 | glfwMakeContextCurrent(gTestEnv->GetOpenGLESWindow()); |
| 973 | } |
Stephen White | 21ce5d2 | 2021-05-17 18:04:48 +0000 | [diff] [blame] | 974 | #endif // defined(DAWN_ENABLE_BACKEND_OPENGLES) |
Ben Clayton | 93a7593 | 2021-07-15 09:09:38 +0000 | [diff] [blame] | 975 | |
| 976 | device.SetLoggingCallback( |
| 977 | [](WGPULoggingType type, char const* message, void*) { |
| 978 | switch (type) { |
| 979 | case WGPULoggingType_Verbose: |
| 980 | dawn::DebugLog() << message; |
| 981 | break; |
| 982 | case WGPULoggingType_Warning: |
| 983 | dawn::WarningLog() << message; |
| 984 | break; |
| 985 | case WGPULoggingType_Error: |
| 986 | dawn::ErrorLog() << message; |
| 987 | break; |
| 988 | default: |
| 989 | dawn::InfoLog() << message; |
| 990 | break; |
| 991 | } |
| 992 | }, |
| 993 | nullptr); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 994 | } |
| 995 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 996 | void DawnTestBase::TearDown() { |
Corentin Wallez | 419e984 | 2018-06-07 13:10:44 +0200 | [diff] [blame] | 997 | FlushWire(); |
| 998 | |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 999 | MapSlotsSynchronously(); |
| 1000 | ResolveExpectations(); |
| 1001 | |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1002 | for (size_t i = 0; i < mReadbackSlots.size(); ++i) { |
| 1003 | mReadbackSlots[i].buffer.Unmap(); |
Corentin Wallez | 7218ed1 | 2017-07-25 11:29:28 -0400 | [diff] [blame] | 1004 | } |
Kai Ninomiya | 2bb8035 | 2020-10-28 21:23:45 +0000 | [diff] [blame] | 1005 | |
| 1006 | if (!UsesWire()) { |
| 1007 | EXPECT_EQ(mLastWarningCount, |
| 1008 | dawn_native::GetDeprecationWarningCountForTesting(device.Get())); |
| 1009 | } |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1010 | } |
| 1011 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 1012 | void DawnTestBase::StartExpectDeviceError() { |
Corentin Wallez | 2dfb3f0 | 2019-02-28 09:45:48 +0000 | [diff] [blame] | 1013 | mExpectError = true; |
| 1014 | mError = false; |
| 1015 | } |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 1016 | bool DawnTestBase::EndExpectDeviceError() { |
Corentin Wallez | 2dfb3f0 | 2019-02-28 09:45:48 +0000 | [diff] [blame] | 1017 | mExpectError = false; |
| 1018 | return mError; |
| 1019 | } |
| 1020 | |
| 1021 | // static |
Corentin Wallez | cab352c | 2019-10-28 13:27:36 +0000 | [diff] [blame] | 1022 | void DawnTestBase::OnDeviceError(WGPUErrorType type, const char* message, void* userdata) { |
| 1023 | ASSERT(type != WGPUErrorType_NoError); |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 1024 | DawnTestBase* self = static_cast<DawnTestBase*>(userdata); |
Corentin Wallez | 2dfb3f0 | 2019-02-28 09:45:48 +0000 | [diff] [blame] | 1025 | |
| 1026 | ASSERT_TRUE(self->mExpectError) << "Got unexpected device error: " << message; |
| 1027 | ASSERT_FALSE(self->mError) << "Got two errors in expect block"; |
| 1028 | self->mError = true; |
| 1029 | } |
| 1030 | |
Kai Ninomiya | 51791e0 | 2021-09-28 11:52:17 +0000 | [diff] [blame] | 1031 | void DawnTestBase::OnDeviceLost(WGPUDeviceLostReason reason, const char* message, void* userdata) { |
Enrico Galli | 101a582 | 2020-08-08 01:05:59 +0000 | [diff] [blame] | 1032 | // Using ADD_FAILURE + ASSERT instead of FAIL to prevent the current test from continuing with a |
| 1033 | // corrupt state. |
| 1034 | ADD_FAILURE() << "Device Lost during test: " << message; |
| 1035 | ASSERT(false); |
Natasha Lee | 0ecc48e | 2020-01-15 19:02:13 +0000 | [diff] [blame] | 1036 | } |
| 1037 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 1038 | std::ostringstream& DawnTestBase::AddBufferExpectation(const char* file, |
| 1039 | int line, |
Corentin Wallez | cab352c | 2019-10-28 13:27:36 +0000 | [diff] [blame] | 1040 | const wgpu::Buffer& buffer, |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 1041 | uint64_t offset, |
| 1042 | uint64_t size, |
| 1043 | detail::Expectation* expectation) { |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1044 | auto readback = ReserveReadback(size); |
| 1045 | |
| 1046 | // We need to enqueue the copy immediately because by the time we resolve the expectation, |
| 1047 | // the buffer might have been modified. |
Corentin Wallez | cab352c | 2019-10-28 13:27:36 +0000 | [diff] [blame] | 1048 | wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); |
Corentin Wallez | e1f0d4e | 2019-02-15 12:54:08 +0000 | [diff] [blame] | 1049 | encoder.CopyBufferToBuffer(buffer, offset, readback.buffer, readback.offset, size); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1050 | |
Corentin Wallez | cab352c | 2019-10-28 13:27:36 +0000 | [diff] [blame] | 1051 | wgpu::CommandBuffer commands = encoder.Finish(); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1052 | queue.Submit(1, &commands); |
| 1053 | |
| 1054 | DeferredExpectation deferred; |
| 1055 | deferred.file = file; |
| 1056 | deferred.line = line; |
| 1057 | deferred.readbackSlot = readback.slot; |
| 1058 | deferred.readbackOffset = readback.offset; |
| 1059 | deferred.size = size; |
Austin Eng | 51ff013 | 2017-07-13 15:10:30 -0400 | [diff] [blame] | 1060 | deferred.rowBytes = size; |
Corentin Wallez | cdf2d8d | 2020-04-24 10:02:43 +0000 | [diff] [blame] | 1061 | deferred.bytesPerRow = size; |
Corentin Wallez | cca9c69 | 2018-09-06 15:26:48 +0200 | [diff] [blame] | 1062 | deferred.expectation.reset(expectation); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1063 | |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1064 | mDeferredExpectations.push_back(std::move(deferred)); |
| 1065 | mDeferredExpectations.back().message = std::make_unique<std::ostringstream>(); |
| 1066 | return *(mDeferredExpectations.back().message.get()); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1067 | } |
| 1068 | |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 1069 | std::ostringstream& DawnTestBase::AddTextureExpectationImpl(const char* file, |
| 1070 | int line, |
| 1071 | detail::Expectation* expectation, |
| 1072 | const wgpu::Texture& texture, |
Yunchao He | 4eb40c1 | 2021-03-31 22:15:53 +0000 | [diff] [blame] | 1073 | wgpu::Origin3D origin, |
| 1074 | wgpu::Extent3D extent, |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 1075 | uint32_t level, |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 1076 | wgpu::TextureAspect aspect, |
| 1077 | uint32_t dataSize, |
| 1078 | uint32_t bytesPerRow) { |
| 1079 | if (bytesPerRow == 0) { |
Yunchao He | 4eb40c1 | 2021-03-31 22:15:53 +0000 | [diff] [blame] | 1080 | bytesPerRow = Align(extent.width * dataSize, kTextureBytesPerRowAlignment); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 1081 | } else { |
Yunchao He | 4eb40c1 | 2021-03-31 22:15:53 +0000 | [diff] [blame] | 1082 | ASSERT(bytesPerRow >= extent.width * dataSize); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 1083 | ASSERT(bytesPerRow == Align(bytesPerRow, kTextureBytesPerRowAlignment)); |
| 1084 | } |
Corentin Wallez | 4cd65f0 | 2017-06-27 00:11:16 -0400 | [diff] [blame] | 1085 | |
Yunchao He | 4eb40c1 | 2021-03-31 22:15:53 +0000 | [diff] [blame] | 1086 | uint32_t rowsPerImage = extent.height; |
| 1087 | uint32_t size = utils::RequiredBytesInCopy(bytesPerRow, rowsPerImage, extent.width, |
Yunchao He | 3e8f3f9 | 2021-04-01 22:40:43 +0000 | [diff] [blame] | 1088 | extent.height, extent.depthOrArrayLayers, dataSize); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 1089 | |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 1090 | auto readback = ReserveReadback(Align(size, 4)); |
Corentin Wallez | 4cd65f0 | 2017-06-27 00:11:16 -0400 | [diff] [blame] | 1091 | |
| 1092 | // We need to enqueue the copy immediately because by the time we resolve the expectation, |
| 1093 | // the texture might have been modified. |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 1094 | wgpu::ImageCopyTexture imageCopyTexture = |
| 1095 | utils::CreateImageCopyTexture(texture, level, origin, aspect); |
Corentin Wallez | 8091584 | 2021-03-04 18:13:45 +0000 | [diff] [blame] | 1096 | wgpu::ImageCopyBuffer imageCopyBuffer = |
| 1097 | utils::CreateImageCopyBuffer(readback.buffer, readback.offset, bytesPerRow, rowsPerImage); |
Corentin Wallez | 4cd65f0 | 2017-06-27 00:11:16 -0400 | [diff] [blame] | 1098 | |
Corentin Wallez | cab352c | 2019-10-28 13:27:36 +0000 | [diff] [blame] | 1099 | wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); |
Yunchao He | 4eb40c1 | 2021-03-31 22:15:53 +0000 | [diff] [blame] | 1100 | encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, &extent); |
Corentin Wallez | e1f0d4e | 2019-02-15 12:54:08 +0000 | [diff] [blame] | 1101 | |
Corentin Wallez | cab352c | 2019-10-28 13:27:36 +0000 | [diff] [blame] | 1102 | wgpu::CommandBuffer commands = encoder.Finish(); |
Corentin Wallez | 4cd65f0 | 2017-06-27 00:11:16 -0400 | [diff] [blame] | 1103 | queue.Submit(1, &commands); |
| 1104 | |
| 1105 | DeferredExpectation deferred; |
| 1106 | deferred.file = file; |
| 1107 | deferred.line = line; |
| 1108 | deferred.readbackSlot = readback.slot; |
| 1109 | deferred.readbackOffset = readback.offset; |
| 1110 | deferred.size = size; |
Yunchao He | 4eb40c1 | 2021-03-31 22:15:53 +0000 | [diff] [blame] | 1111 | deferred.rowBytes = extent.width * dataSize; |
Corentin Wallez | cdf2d8d | 2020-04-24 10:02:43 +0000 | [diff] [blame] | 1112 | deferred.bytesPerRow = bytesPerRow; |
Corentin Wallez | cca9c69 | 2018-09-06 15:26:48 +0200 | [diff] [blame] | 1113 | deferred.expectation.reset(expectation); |
Corentin Wallez | 4cd65f0 | 2017-06-27 00:11:16 -0400 | [diff] [blame] | 1114 | |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1115 | mDeferredExpectations.push_back(std::move(deferred)); |
| 1116 | mDeferredExpectations.back().message = std::make_unique<std::ostringstream>(); |
| 1117 | return *(mDeferredExpectations.back().message.get()); |
Corentin Wallez | 4cd65f0 | 2017-06-27 00:11:16 -0400 | [diff] [blame] | 1118 | } |
| 1119 | |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 1120 | std::ostringstream& DawnTestBase::ExpectSampledFloatDataImpl(wgpu::TextureView textureView, |
| 1121 | const char* wgslTextureType, |
| 1122 | uint32_t width, |
| 1123 | uint32_t height, |
| 1124 | uint32_t componentCount, |
| 1125 | uint32_t sampleCount, |
| 1126 | detail::Expectation* expectation) { |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 1127 | std::ostringstream shaderSource; |
| 1128 | shaderSource << "let width : u32 = " << width << "u;\n"; |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 1129 | shaderSource << "[[group(0), binding(0)]] var tex : " << wgslTextureType << ";\n"; |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 1130 | shaderSource << R"( |
| 1131 | [[block]] struct Result { |
| 1132 | values : array<f32>; |
| 1133 | }; |
Ben Clayton | 15eba9a | 2021-06-08 15:36:44 +0000 | [diff] [blame] | 1134 | [[group(0), binding(1)]] var<storage, read_write> result : Result; |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 1135 | )"; |
| 1136 | shaderSource << "let componentCount : u32 = " << componentCount << "u;\n"; |
| 1137 | shaderSource << "let sampleCount : u32 = " << sampleCount << "u;\n"; |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 1138 | |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 1139 | shaderSource << "fn doTextureLoad(t: " << wgslTextureType |
| 1140 | << ", coord: vec2<i32>, sample: u32, component: u32) -> f32"; |
| 1141 | if (sampleCount > 1) { |
| 1142 | shaderSource << R"({ |
| 1143 | return textureLoad(tex, coord, i32(sample))[component]; |
| 1144 | })"; |
| 1145 | } else { |
| 1146 | if (strcmp(wgslTextureType, "texture_depth_2d") == 0) { |
| 1147 | ASSERT(componentCount == 1); |
| 1148 | shaderSource << R"({ |
| 1149 | return textureLoad(tex, coord, 0); |
| 1150 | })"; |
| 1151 | } else { |
| 1152 | shaderSource << R"({ |
| 1153 | return textureLoad(tex, coord, 0)[component]; |
| 1154 | })"; |
| 1155 | } |
| 1156 | } |
| 1157 | shaderSource << R"( |
Sarah | 2a57db7 | 2021-06-23 19:19:06 +0000 | [diff] [blame] | 1158 | [[stage(compute), workgroup_size(1)]] fn main( |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 1159 | [[builtin(global_invocation_id)]] GlobalInvocationId : vec3<u32> |
| 1160 | ) { |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 1161 | let baseOutIndex = GlobalInvocationId.y * width + GlobalInvocationId.x; |
| 1162 | for (var s = 0u; s < sampleCount; s = s + 1u) { |
| 1163 | for (var c = 0u; c < componentCount; c = c + 1u) { |
| 1164 | result.values[ |
| 1165 | baseOutIndex * sampleCount * componentCount + |
| 1166 | s * componentCount + |
| 1167 | c |
| 1168 | ] = doTextureLoad(tex, vec2<i32>(GlobalInvocationId.xy), s, c); |
| 1169 | } |
| 1170 | } |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 1171 | } |
| 1172 | )"; |
| 1173 | |
| 1174 | wgpu::ShaderModule csModule = utils::CreateShaderModule(device, shaderSource.str().c_str()); |
| 1175 | |
| 1176 | wgpu::ComputePipelineDescriptor pipelineDescriptor; |
Brandon Jones | 0d50a2c | 2021-06-09 18:07:32 +0000 | [diff] [blame] | 1177 | pipelineDescriptor.compute.module = csModule; |
| 1178 | pipelineDescriptor.compute.entryPoint = "main"; |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 1179 | |
| 1180 | wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDescriptor); |
| 1181 | |
| 1182 | // Create and initialize the slot buffer so that it won't unexpectedly affect the count of |
| 1183 | // resources lazily cleared. |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 1184 | const std::vector<float> initialBufferData(width * height * componentCount * sampleCount, 0.f); |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 1185 | wgpu::Buffer readbackBuffer = utils::CreateBufferFromData( |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 1186 | device, initialBufferData.data(), sizeof(float) * initialBufferData.size(), |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 1187 | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::Storage); |
| 1188 | |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 1189 | wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), |
| 1190 | {{0, textureView}, {1, readbackBuffer}}); |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 1191 | |
| 1192 | wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); |
| 1193 | wgpu::ComputePassEncoder pass = commandEncoder.BeginComputePass(); |
| 1194 | pass.SetPipeline(pipeline); |
| 1195 | pass.SetBindGroup(0, bindGroup); |
| 1196 | pass.Dispatch(width, height); |
| 1197 | pass.EndPass(); |
| 1198 | wgpu::CommandBuffer commands = commandEncoder.Finish(); |
| 1199 | queue.Submit(1, &commands); |
| 1200 | |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 1201 | return EXPECT_BUFFER(readbackBuffer, 0, initialBufferData.size() * sizeof(float), expectation); |
| 1202 | } |
| 1203 | |
| 1204 | std::ostringstream& DawnTestBase::ExpectSampledFloatData(wgpu::Texture texture, |
| 1205 | uint32_t width, |
| 1206 | uint32_t height, |
| 1207 | uint32_t componentCount, |
| 1208 | uint32_t arrayLayer, |
| 1209 | uint32_t mipLevel, |
| 1210 | detail::Expectation* expectation) { |
| 1211 | wgpu::TextureViewDescriptor viewDesc = {}; |
| 1212 | viewDesc.dimension = wgpu::TextureViewDimension::e2D; |
| 1213 | viewDesc.baseMipLevel = mipLevel; |
| 1214 | viewDesc.mipLevelCount = 1; |
| 1215 | viewDesc.baseArrayLayer = arrayLayer; |
| 1216 | viewDesc.arrayLayerCount = 1; |
| 1217 | |
| 1218 | return ExpectSampledFloatDataImpl(texture.CreateView(&viewDesc), "texture_2d<f32>", width, |
| 1219 | height, componentCount, 1, expectation); |
| 1220 | } |
| 1221 | |
| 1222 | std::ostringstream& DawnTestBase::ExpectMultisampledFloatData(wgpu::Texture texture, |
| 1223 | uint32_t width, |
| 1224 | uint32_t height, |
| 1225 | uint32_t componentCount, |
| 1226 | uint32_t sampleCount, |
| 1227 | uint32_t arrayLayer, |
| 1228 | uint32_t mipLevel, |
| 1229 | detail::Expectation* expectation) { |
| 1230 | wgpu::TextureViewDescriptor viewDesc = {}; |
| 1231 | viewDesc.dimension = wgpu::TextureViewDimension::e2D; |
| 1232 | viewDesc.baseMipLevel = mipLevel; |
| 1233 | viewDesc.mipLevelCount = 1; |
| 1234 | viewDesc.baseArrayLayer = arrayLayer; |
| 1235 | viewDesc.arrayLayerCount = 1; |
| 1236 | |
| 1237 | return ExpectSampledFloatDataImpl(texture.CreateView(&viewDesc), "texture_multisampled_2d<f32>", |
| 1238 | width, height, componentCount, sampleCount, expectation); |
| 1239 | } |
| 1240 | |
| 1241 | std::ostringstream& DawnTestBase::ExpectSampledDepthData(wgpu::Texture texture, |
| 1242 | uint32_t width, |
| 1243 | uint32_t height, |
| 1244 | uint32_t arrayLayer, |
| 1245 | uint32_t mipLevel, |
| 1246 | detail::Expectation* expectation) { |
| 1247 | wgpu::TextureViewDescriptor viewDesc = {}; |
| 1248 | viewDesc.aspect = wgpu::TextureAspect::DepthOnly; |
| 1249 | viewDesc.dimension = wgpu::TextureViewDimension::e2D; |
| 1250 | viewDesc.baseMipLevel = mipLevel; |
| 1251 | viewDesc.mipLevelCount = 1; |
| 1252 | viewDesc.baseArrayLayer = arrayLayer; |
| 1253 | viewDesc.arrayLayerCount = 1; |
| 1254 | |
| 1255 | return ExpectSampledFloatDataImpl(texture.CreateView(&viewDesc), "texture_depth_2d", width, |
| 1256 | height, 1, 1, expectation); |
Austin Eng | 735d504 | 2021-06-08 00:24:43 +0000 | [diff] [blame] | 1257 | } |
| 1258 | |
| 1259 | std::ostringstream& DawnTestBase::ExpectAttachmentDepthStencilTestData( |
| 1260 | wgpu::Texture texture, |
| 1261 | wgpu::TextureFormat format, |
| 1262 | uint32_t width, |
| 1263 | uint32_t height, |
| 1264 | uint32_t arrayLayer, |
| 1265 | uint32_t mipLevel, |
| 1266 | std::vector<float> expectedDepth, |
| 1267 | uint8_t* expectedStencil) { |
| 1268 | wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); |
| 1269 | |
| 1270 | // Make the color attachment that we'll use to read back. |
| 1271 | wgpu::TextureDescriptor colorTexDesc = {}; |
| 1272 | colorTexDesc.size = {width, height, 1}; |
| 1273 | colorTexDesc.format = wgpu::TextureFormat::R32Uint; |
| 1274 | colorTexDesc.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc; |
| 1275 | wgpu::Texture colorTexture = device.CreateTexture(&colorTexDesc); |
| 1276 | |
| 1277 | wgpu::Texture depthDataTexture = nullptr; |
| 1278 | if (expectedDepth.size() > 0) { |
| 1279 | // Make a sampleable texture to store the depth data. We'll sample this in the |
| 1280 | // shader to output depth. |
| 1281 | wgpu::TextureDescriptor depthDataDesc = {}; |
| 1282 | depthDataDesc.size = {width, height, 1}; |
| 1283 | depthDataDesc.format = wgpu::TextureFormat::R32Float; |
Brandon Jones | 27e17a6 | 2021-08-10 04:07:37 +0000 | [diff] [blame] | 1284 | depthDataDesc.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst; |
Austin Eng | 735d504 | 2021-06-08 00:24:43 +0000 | [diff] [blame] | 1285 | depthDataTexture = device.CreateTexture(&depthDataDesc); |
| 1286 | |
| 1287 | // Upload the depth data. |
| 1288 | wgpu::ImageCopyTexture imageCopyTexture = |
| 1289 | utils::CreateImageCopyTexture(depthDataTexture, 0, {0, 0, 0}); |
| 1290 | wgpu::TextureDataLayout textureDataLayout = |
| 1291 | utils::CreateTextureDataLayout(0, sizeof(float) * width); |
| 1292 | wgpu::Extent3D copyExtent = {width, height, 1}; |
| 1293 | |
| 1294 | queue.WriteTexture(&imageCopyTexture, expectedDepth.data(), |
| 1295 | sizeof(float) * expectedDepth.size(), &textureDataLayout, ©Extent); |
| 1296 | } |
| 1297 | |
| 1298 | // Pipeline for a full screen quad. |
| 1299 | utils::ComboRenderPipelineDescriptor pipelineDescriptor; |
| 1300 | |
| 1301 | pipelineDescriptor.vertex.module = utils::CreateShaderModule(device, R"( |
| 1302 | [[stage(vertex)]] |
| 1303 | fn main([[builtin(vertex_index)]] VertexIndex : u32) -> [[builtin(position)]] vec4<f32> { |
Corentin Wallez | b86e45f | 2021-06-17 21:36:11 +0000 | [diff] [blame] | 1304 | var pos = array<vec2<f32>, 3>( |
Austin Eng | 735d504 | 2021-06-08 00:24:43 +0000 | [diff] [blame] | 1305 | vec2<f32>(-1.0, -1.0), |
| 1306 | vec2<f32>( 3.0, -1.0), |
| 1307 | vec2<f32>(-1.0, 3.0)); |
| 1308 | return vec4<f32>(pos[VertexIndex], 0.0, 1.0); |
| 1309 | })"); |
| 1310 | |
| 1311 | if (depthDataTexture) { |
| 1312 | // Sample the input texture and write out depth. |result| will only be set to 1 if we |
| 1313 | // pass the depth test. |
| 1314 | pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"( |
| 1315 | [[group(0), binding(0)]] var texture0 : texture_2d<f32>; |
| 1316 | |
| 1317 | struct FragmentOut { |
| 1318 | [[location(0)]] result : u32; |
| 1319 | [[builtin(frag_depth)]] fragDepth : f32; |
| 1320 | }; |
| 1321 | |
| 1322 | [[stage(fragment)]] |
| 1323 | fn main([[builtin(position)]] FragCoord : vec4<f32>) -> FragmentOut { |
| 1324 | var output : FragmentOut; |
| 1325 | output.result = 1u; |
| 1326 | output.fragDepth = textureLoad(texture0, vec2<i32>(FragCoord.xy), 0)[0]; |
| 1327 | return output; |
| 1328 | })"); |
| 1329 | } else { |
| 1330 | pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"( |
| 1331 | [[stage(fragment)]] |
| 1332 | fn main() -> [[location(0)]] u32 { |
| 1333 | return 1u; |
| 1334 | })"); |
| 1335 | } |
| 1336 | |
| 1337 | wgpu::DepthStencilState* depthStencil = pipelineDescriptor.EnableDepthStencil(format); |
| 1338 | if (depthDataTexture) { |
| 1339 | // Pass the depth test only if the depth is equal. |
| 1340 | depthStencil->depthCompare = wgpu::CompareFunction::Equal; |
| 1341 | |
| 1342 | // TODO(jiawei.shao@intel.com): The Intel Mesa Vulkan driver can't set gl_FragDepth unless |
| 1343 | // depthWriteEnabled == true. This either needs to be fixed in the driver or restricted by |
| 1344 | // the WebGPU API. |
| 1345 | depthStencil->depthWriteEnabled = true; |
| 1346 | } |
| 1347 | |
| 1348 | if (expectedStencil != nullptr) { |
| 1349 | // Pass the stencil test only if the stencil is equal. |
| 1350 | depthStencil->stencilFront.compare = wgpu::CompareFunction::Equal; |
| 1351 | } |
| 1352 | |
| 1353 | pipelineDescriptor.cTargets[0].format = colorTexDesc.format; |
| 1354 | |
| 1355 | wgpu::TextureViewDescriptor viewDesc = {}; |
| 1356 | viewDesc.baseMipLevel = mipLevel; |
| 1357 | viewDesc.mipLevelCount = 1; |
| 1358 | viewDesc.baseArrayLayer = arrayLayer; |
| 1359 | viewDesc.arrayLayerCount = 1; |
| 1360 | |
| 1361 | utils::ComboRenderPassDescriptor passDescriptor({colorTexture.CreateView()}, |
| 1362 | texture.CreateView(&viewDesc)); |
| 1363 | passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load; |
| 1364 | passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load; |
| 1365 | |
| 1366 | wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDescriptor); |
| 1367 | |
| 1368 | wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor); |
| 1369 | if (expectedStencil != nullptr) { |
| 1370 | pass.SetStencilReference(*expectedStencil); |
| 1371 | } |
| 1372 | pass.SetPipeline(pipeline); |
| 1373 | if (depthDataTexture) { |
| 1374 | // Bind the depth data texture. |
| 1375 | pass.SetBindGroup(0, utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), |
| 1376 | {{0, depthDataTexture.CreateView()}})); |
| 1377 | } |
| 1378 | pass.Draw(3); |
| 1379 | pass.EndPass(); |
| 1380 | |
| 1381 | wgpu::CommandBuffer commands = commandEncoder.Finish(); |
| 1382 | queue.Submit(1, &commands); |
| 1383 | |
| 1384 | std::vector<uint32_t> colorData(width * height, 1u); |
| 1385 | return EXPECT_TEXTURE_EQ(colorData.data(), colorTexture, {0, 0}, {width, height}); |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 1386 | } |
| 1387 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 1388 | void DawnTestBase::WaitABit() { |
Corentin Wallez | 134e080 | 2017-07-17 17:13:57 -0400 | [diff] [blame] | 1389 | device.Tick(); |
Corentin Wallez | 419e984 | 2018-06-07 13:10:44 +0200 | [diff] [blame] | 1390 | FlushWire(); |
| 1391 | |
Corentin Wallez | 134e080 | 2017-07-17 17:13:57 -0400 | [diff] [blame] | 1392 | utils::USleep(100); |
| 1393 | } |
| 1394 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 1395 | void DawnTestBase::FlushWire() { |
Corentin Wallez | 0ee9859 | 2019-05-01 12:57:27 +0000 | [diff] [blame] | 1396 | if (gTestEnv->UsesWire()) { |
Austin Eng | e58d5a3 | 2021-01-27 22:54:04 +0000 | [diff] [blame] | 1397 | bool C2SFlushed = mWireHelper->FlushClient(); |
| 1398 | bool S2CFlushed = mWireHelper->FlushServer(); |
Corentin Wallez | 6be3b97 | 2019-02-11 23:34:52 +0000 | [diff] [blame] | 1399 | ASSERT(C2SFlushed); |
| 1400 | ASSERT(S2CFlushed); |
Corentin Wallez | 419e984 | 2018-06-07 13:10:44 +0200 | [diff] [blame] | 1401 | } |
| 1402 | } |
| 1403 | |
Natasha Lee | 51af1b4 | 2020-10-12 22:32:33 +0000 | [diff] [blame] | 1404 | void DawnTestBase::WaitForAllOperations() { |
Corentin Wallez | 4165c1c | 2021-02-25 21:47:15 +0000 | [diff] [blame] | 1405 | bool done = false; |
| 1406 | device.GetQueue().OnSubmittedWorkDone( |
| 1407 | 0u, [](WGPUQueueWorkDoneStatus, void* userdata) { *static_cast<bool*>(userdata) = true; }, |
| 1408 | &done); |
| 1409 | while (!done) { |
Natasha Lee | 51af1b4 | 2020-10-12 22:32:33 +0000 | [diff] [blame] | 1410 | WaitABit(); |
| 1411 | } |
| 1412 | } |
| 1413 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 1414 | DawnTestBase::ReadbackReservation DawnTestBase::ReserveReadback(uint64_t readbackSize) { |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1415 | ReadbackSlot slot; |
| 1416 | slot.bufferSize = readbackSize; |
Jiawei Shao | ef74473 | 2020-08-23 06:08:05 +0000 | [diff] [blame] | 1417 | |
| 1418 | // Create and initialize the slot buffer so that it won't unexpectedly affect the count of |
| 1419 | // resource lazy clear in the tests. |
| 1420 | const std::vector<uint8_t> initialBufferData(readbackSize, 0u); |
| 1421 | slot.buffer = |
| 1422 | utils::CreateBufferFromData(device, initialBufferData.data(), readbackSize, |
| 1423 | wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1424 | |
| 1425 | ReadbackReservation reservation; |
Corentin Wallez | aa7109c | 2018-10-25 10:42:49 +0000 | [diff] [blame] | 1426 | reservation.buffer = slot.buffer; |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1427 | reservation.slot = mReadbackSlots.size(); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1428 | reservation.offset = 0; |
| 1429 | |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1430 | mReadbackSlots.push_back(std::move(slot)); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1431 | return reservation; |
| 1432 | } |
| 1433 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 1434 | void DawnTestBase::MapSlotsSynchronously() { |
Corentin Wallez | a4da032 | 2018-07-18 15:18:25 +0200 | [diff] [blame] | 1435 | // Initialize numPendingMapOperations before mapping, just in case the callback is called |
| 1436 | // immediately. |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1437 | mNumPendingMapOperations = mReadbackSlots.size(); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1438 | |
| 1439 | // Map all readback slots |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1440 | for (size_t i = 0; i < mReadbackSlots.size(); ++i) { |
Corentin Wallez | 839053b | 2019-05-29 13:03:50 +0000 | [diff] [blame] | 1441 | MapReadUserdata* userdata = new MapReadUserdata{this, i}; |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1442 | |
Corentin Wallez | 2a232ba | 2020-07-16 16:35:40 +0000 | [diff] [blame] | 1443 | const ReadbackSlot& slot = mReadbackSlots[i]; |
Zhaoming Jiang | 2a5b981 | 2021-10-18 05:30:39 +0000 | [diff] [blame] | 1444 | slot.buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize, SlotMapCallback, |
| 1445 | userdata); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1446 | } |
| 1447 | |
| 1448 | // Busy wait until all map operations are done. |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1449 | while (mNumPendingMapOperations != 0) { |
Corentin Wallez | 134e080 | 2017-07-17 17:13:57 -0400 | [diff] [blame] | 1450 | WaitABit(); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1451 | } |
| 1452 | } |
| 1453 | |
| 1454 | // static |
Corentin Wallez | 2a232ba | 2020-07-16 16:35:40 +0000 | [diff] [blame] | 1455 | void DawnTestBase::SlotMapCallback(WGPUBufferMapAsyncStatus status, void* userdata_) { |
Corentin Wallez | cab352c | 2019-10-28 13:27:36 +0000 | [diff] [blame] | 1456 | DAWN_ASSERT(status == WGPUBufferMapAsyncStatus_Success); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1457 | |
Corentin Wallez | 2a232ba | 2020-07-16 16:35:40 +0000 | [diff] [blame] | 1458 | std::unique_ptr<MapReadUserdata> userdata(static_cast<MapReadUserdata*>(userdata_)); |
| 1459 | DawnTestBase* test = userdata->test; |
| 1460 | ReadbackSlot* slot = &test->mReadbackSlots[userdata->slot]; |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1461 | |
Corentin Wallez | 2a232ba | 2020-07-16 16:35:40 +0000 | [diff] [blame] | 1462 | slot->mappedData = slot->buffer.GetConstMappedRange(); |
| 1463 | test->mNumPendingMapOperations--; |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1464 | } |
| 1465 | |
Austin Eng | ca0eac3 | 2019-08-28 23:18:10 +0000 | [diff] [blame] | 1466 | void DawnTestBase::ResolveExpectations() { |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1467 | for (const auto& expectation : mDeferredExpectations) { |
Corentin Wallez | 83a9c9d | 2018-07-18 13:37:54 +0200 | [diff] [blame] | 1468 | DAWN_ASSERT(mReadbackSlots[expectation.readbackSlot].mappedData != nullptr); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1469 | |
| 1470 | // Get a pointer to the mapped copy of the data for the expectation. |
Corentin Wallez | a4da032 | 2018-07-18 15:18:25 +0200 | [diff] [blame] | 1471 | const char* data = |
Rafael Cintron | f54bb68 | 2019-05-03 00:58:27 +0000 | [diff] [blame] | 1472 | static_cast<const char*>(mReadbackSlots[expectation.readbackSlot].mappedData); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1473 | data += expectation.readbackOffset; |
| 1474 | |
Austin Eng | 51ff013 | 2017-07-13 15:10:30 -0400 | [diff] [blame] | 1475 | uint32_t size; |
| 1476 | std::vector<char> packedData; |
Corentin Wallez | cdf2d8d | 2020-04-24 10:02:43 +0000 | [diff] [blame] | 1477 | if (expectation.rowBytes != expectation.bytesPerRow) { |
| 1478 | DAWN_ASSERT(expectation.bytesPerRow > expectation.rowBytes); |
Corentin Wallez | a4da032 | 2018-07-18 15:18:25 +0200 | [diff] [blame] | 1479 | uint32_t rowCount = |
Corentin Wallez | cdf2d8d | 2020-04-24 10:02:43 +0000 | [diff] [blame] | 1480 | (expectation.size + expectation.bytesPerRow - 1) / expectation.bytesPerRow; |
Austin Eng | 51ff013 | 2017-07-13 15:10:30 -0400 | [diff] [blame] | 1481 | uint32_t packedSize = rowCount * expectation.rowBytes; |
| 1482 | packedData.resize(packedSize); |
| 1483 | for (uint32_t r = 0; r < rowCount; ++r) { |
| 1484 | for (uint32_t i = 0; i < expectation.rowBytes; ++i) { |
Corentin Wallez | cdf2d8d | 2020-04-24 10:02:43 +0000 | [diff] [blame] | 1485 | packedData[i + r * expectation.rowBytes] = |
| 1486 | data[i + r * expectation.bytesPerRow]; |
Austin Eng | 51ff013 | 2017-07-13 15:10:30 -0400 | [diff] [blame] | 1487 | } |
| 1488 | } |
| 1489 | data = packedData.data(); |
| 1490 | size = packedSize; |
| 1491 | } else { |
| 1492 | size = expectation.size; |
| 1493 | } |
| 1494 | |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1495 | // Get the result for the expectation and add context to failures |
Austin Eng | 51ff013 | 2017-07-13 15:10:30 -0400 | [diff] [blame] | 1496 | testing::AssertionResult result = expectation.expectation->Check(data, size); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1497 | if (!result) { |
Corentin Wallez | a4da032 | 2018-07-18 15:18:25 +0200 | [diff] [blame] | 1498 | result << " Expectation created at " << expectation.file << ":" << expectation.line |
| 1499 | << std::endl; |
Austin Eng | 4234c39 | 2017-07-17 09:37:08 -0400 | [diff] [blame] | 1500 | result << expectation.message->str(); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1501 | } |
| 1502 | |
| 1503 | EXPECT_TRUE(result); |
| 1504 | } |
| 1505 | } |
| 1506 | |
Bryan Bernhart | 41b3f9c | 2020-11-20 20:38:37 +0000 | [diff] [blame] | 1507 | std::unique_ptr<dawn_platform::Platform> DawnTestBase::CreateTestPlatform() { |
| 1508 | return nullptr; |
| 1509 | } |
| 1510 | |
Corentin Wallez | 4cd65f0 | 2017-06-27 00:11:16 -0400 | [diff] [blame] | 1511 | bool RGBA8::operator==(const RGBA8& other) const { |
| 1512 | return r == other.r && g == other.g && b == other.b && a == other.a; |
| 1513 | } |
| 1514 | |
| 1515 | bool RGBA8::operator!=(const RGBA8& other) const { |
| 1516 | return !(*this == other); |
| 1517 | } |
| 1518 | |
shrekshao | f8c5e4a | 2020-12-24 03:11:17 +0000 | [diff] [blame] | 1519 | bool RGBA8::operator<=(const RGBA8& other) const { |
| 1520 | return (r <= other.r && g <= other.g && b <= other.b && a <= other.a); |
| 1521 | } |
| 1522 | |
| 1523 | bool RGBA8::operator>=(const RGBA8& other) const { |
| 1524 | return (r >= other.r && g >= other.g && b >= other.b && a >= other.a); |
| 1525 | } |
| 1526 | |
Corentin Wallez | a4da032 | 2018-07-18 15:18:25 +0200 | [diff] [blame] | 1527 | std::ostream& operator<<(std::ostream& stream, const RGBA8& color) { |
| 1528 | return stream << "RGBA8(" << static_cast<int>(color.r) << ", " << static_cast<int>(color.g) |
| 1529 | << ", " << static_cast<int>(color.b) << ", " << static_cast<int>(color.a) << ")"; |
Corentin Wallez | 4cd65f0 | 2017-06-27 00:11:16 -0400 | [diff] [blame] | 1530 | } |
| 1531 | |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1532 | namespace detail { |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 1533 | std::vector<AdapterTestParam> GetAvailableAdapterTestParamsForBackends( |
| 1534 | const BackendTestConfig* params, |
| 1535 | size_t numParams) { |
Austin Eng | 25c747c | 2020-05-15 16:07:12 +0000 | [diff] [blame] | 1536 | ASSERT(gTestEnv != nullptr); |
Austin Eng | da722ad | 2020-05-15 20:28:05 +0000 | [diff] [blame] | 1537 | return gTestEnv->GetAvailableAdapterTestParamsForBackends(params, numParams); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1538 | } |
| 1539 | |
| 1540 | // Helper classes to set expectations |
| 1541 | |
shrekshao | bdc029e | 2021-07-19 23:27:27 +0000 | [diff] [blame] | 1542 | template <typename T, typename U> |
| 1543 | ExpectEq<T, U>::ExpectEq(T singleValue, T tolerance) : mTolerance(tolerance) { |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1544 | mExpected.push_back(singleValue); |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1545 | } |
| 1546 | |
shrekshao | bdc029e | 2021-07-19 23:27:27 +0000 | [diff] [blame] | 1547 | template <typename T, typename U> |
| 1548 | ExpectEq<T, U>::ExpectEq(const T* values, const unsigned int count, T tolerance) |
Austin Eng | 735d504 | 2021-06-08 00:24:43 +0000 | [diff] [blame] | 1549 | : mTolerance(tolerance) { |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1550 | mExpected.assign(values, values + count); |
Austin Eng | 49fe566 | 2017-07-04 10:53:42 -0400 | [diff] [blame] | 1551 | } |
| 1552 | |
Austin Eng | 735d504 | 2021-06-08 00:24:43 +0000 | [diff] [blame] | 1553 | namespace { |
| 1554 | |
shrekshao | bdc029e | 2021-07-19 23:27:27 +0000 | [diff] [blame] | 1555 | template <typename T, typename U = T> |
| 1556 | testing::AssertionResult CheckImpl(const T& expected, const U& actual, const T& tolerance) { |
Austin Eng | 735d504 | 2021-06-08 00:24:43 +0000 | [diff] [blame] | 1557 | ASSERT(tolerance == T{}); |
| 1558 | if (expected != actual) { |
| 1559 | return testing::AssertionFailure() << expected << ", actual " << actual; |
| 1560 | } |
| 1561 | return testing::AssertionSuccess(); |
| 1562 | } |
| 1563 | |
| 1564 | template <> |
| 1565 | testing::AssertionResult CheckImpl<float>(const float& expected, |
| 1566 | const float& actual, |
| 1567 | const float& tolerance) { |
| 1568 | if (abs(expected - actual) > tolerance) { |
| 1569 | return tolerance == 0.0 |
| 1570 | ? testing::AssertionFailure() << expected << ", actual " << actual |
| 1571 | : testing::AssertionFailure() << "within " << tolerance << " of " |
| 1572 | << expected << ", actual " << actual; |
| 1573 | } |
| 1574 | return testing::AssertionSuccess(); |
| 1575 | } |
| 1576 | |
shrekshao | bdc029e | 2021-07-19 23:27:27 +0000 | [diff] [blame] | 1577 | // Interpret uint16_t as float16 |
| 1578 | // This is mostly for reading float16 output from textures |
| 1579 | template <> |
| 1580 | testing::AssertionResult CheckImpl<float, uint16_t>(const float& expected, |
| 1581 | const uint16_t& actual, |
| 1582 | const float& tolerance) { |
| 1583 | float actualF32 = Float16ToFloat32(actual); |
| 1584 | if (abs(expected - actualF32) > tolerance) { |
| 1585 | return tolerance == 0.0 |
| 1586 | ? testing::AssertionFailure() << expected << ", actual " << actualF32 |
| 1587 | : testing::AssertionFailure() << "within " << tolerance << " of " |
| 1588 | << expected << ", actual " << actualF32; |
| 1589 | } |
| 1590 | return testing::AssertionSuccess(); |
| 1591 | } |
| 1592 | |
Austin Eng | 735d504 | 2021-06-08 00:24:43 +0000 | [diff] [blame] | 1593 | } // namespace |
| 1594 | |
shrekshao | bdc029e | 2021-07-19 23:27:27 +0000 | [diff] [blame] | 1595 | template <typename T, typename U> |
| 1596 | testing::AssertionResult ExpectEq<T, U>::Check(const void* data, size_t size) { |
| 1597 | DAWN_ASSERT(size == sizeof(U) * mExpected.size()); |
| 1598 | const U* actual = static_cast<const U*>(data); |
Austin Eng | 1b8c64d | 2017-07-17 09:37:46 -0400 | [diff] [blame] | 1599 | |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1600 | for (size_t i = 0; i < mExpected.size(); ++i) { |
Austin Eng | 735d504 | 2021-06-08 00:24:43 +0000 | [diff] [blame] | 1601 | testing::AssertionResult check = CheckImpl(mExpected[i], actual[i], mTolerance); |
| 1602 | if (!check) { |
Corentin Wallez | a4da032 | 2018-07-18 15:18:25 +0200 | [diff] [blame] | 1603 | testing::AssertionResult result = testing::AssertionFailure() |
| 1604 | << "Expected data[" << i << "] to be " |
Austin Eng | 735d504 | 2021-06-08 00:24:43 +0000 | [diff] [blame] | 1605 | << check.message() << std::endl; |
Austin Eng | 1b8c64d | 2017-07-17 09:37:46 -0400 | [diff] [blame] | 1606 | |
Corentin Wallez | d5d77af | 2017-11-23 11:51:16 -0800 | [diff] [blame] | 1607 | if (mExpected.size() <= 1024) { |
Austin Eng | 1b8c64d | 2017-07-17 09:37:46 -0400 | [diff] [blame] | 1608 | result << "Expected:" << std::endl; |
shrekshao | f8c5e4a | 2020-12-24 03:11:17 +0000 | [diff] [blame] | 1609 | printBuffer(result, mExpected.data(), mExpected.size()); |
Austin Eng | 1b8c64d | 2017-07-17 09:37:46 -0400 | [diff] [blame] | 1610 | |
| 1611 | result << "Actual:" << std::endl; |
shrekshao | f8c5e4a | 2020-12-24 03:11:17 +0000 | [diff] [blame] | 1612 | printBuffer(result, actual, mExpected.size()); |
Austin Eng | 1b8c64d | 2017-07-17 09:37:46 -0400 | [diff] [blame] | 1613 | } |
| 1614 | |
| 1615 | return result; |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1616 | } |
| 1617 | } |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1618 | return testing::AssertionSuccess(); |
| 1619 | } |
| 1620 | |
Stephen White | e5ae327 | 2018-02-04 11:07:02 -0500 | [diff] [blame] | 1621 | template class ExpectEq<uint8_t>; |
Xinghua Cao | db8f804 | 2020-06-08 12:18:21 +0000 | [diff] [blame] | 1622 | template class ExpectEq<uint16_t>; |
Corentin Wallez | eaae746 | 2017-06-16 18:34:35 -0400 | [diff] [blame] | 1623 | template class ExpectEq<uint32_t>; |
Hao Li | c0acb25 | 2020-08-04 06:41:56 +0000 | [diff] [blame] | 1624 | template class ExpectEq<uint64_t>; |
Corentin Wallez | 4cd65f0 | 2017-06-27 00:11:16 -0400 | [diff] [blame] | 1625 | template class ExpectEq<RGBA8>; |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 1626 | template class ExpectEq<float>; |
shrekshao | bdc029e | 2021-07-19 23:27:27 +0000 | [diff] [blame] | 1627 | template class ExpectEq<float, uint16_t>; |
shrekshao | f8c5e4a | 2020-12-24 03:11:17 +0000 | [diff] [blame] | 1628 | |
| 1629 | template <typename T> |
| 1630 | ExpectBetweenColors<T>::ExpectBetweenColors(T value0, T value1) { |
| 1631 | T l, h; |
| 1632 | l.r = std::min(value0.r, value1.r); |
| 1633 | l.g = std::min(value0.g, value1.g); |
| 1634 | l.b = std::min(value0.b, value1.b); |
| 1635 | l.a = std::min(value0.a, value1.a); |
| 1636 | |
| 1637 | h.r = std::max(value0.r, value1.r); |
| 1638 | h.g = std::max(value0.g, value1.g); |
| 1639 | h.b = std::max(value0.b, value1.b); |
| 1640 | h.a = std::max(value0.a, value1.a); |
| 1641 | |
| 1642 | mLowerColorChannels.push_back(l); |
| 1643 | mHigherColorChannels.push_back(h); |
| 1644 | |
| 1645 | mValues0.push_back(value0); |
| 1646 | mValues1.push_back(value1); |
| 1647 | } |
| 1648 | |
| 1649 | template <typename T> |
| 1650 | testing::AssertionResult ExpectBetweenColors<T>::Check(const void* data, size_t size) { |
| 1651 | DAWN_ASSERT(size == sizeof(T) * mLowerColorChannels.size()); |
| 1652 | DAWN_ASSERT(mHigherColorChannels.size() == mLowerColorChannels.size()); |
| 1653 | DAWN_ASSERT(mValues0.size() == mValues1.size()); |
| 1654 | DAWN_ASSERT(mValues0.size() == mLowerColorChannels.size()); |
| 1655 | |
| 1656 | const T* actual = static_cast<const T*>(data); |
| 1657 | |
| 1658 | for (size_t i = 0; i < mLowerColorChannels.size(); ++i) { |
| 1659 | if (!(actual[i] >= mLowerColorChannels[i] && actual[i] <= mHigherColorChannels[i])) { |
| 1660 | testing::AssertionResult result = testing::AssertionFailure() |
| 1661 | << "Expected data[" << i << "] to be between " |
| 1662 | << mValues0[i] << " and " << mValues1[i] |
| 1663 | << ", actual " << actual[i] << std::endl; |
| 1664 | |
| 1665 | if (mLowerColorChannels.size() <= 1024) { |
| 1666 | result << "Expected between:" << std::endl; |
| 1667 | printBuffer(result, mValues0.data(), mLowerColorChannels.size()); |
| 1668 | result << "and" << std::endl; |
| 1669 | printBuffer(result, mValues1.data(), mLowerColorChannels.size()); |
| 1670 | |
| 1671 | result << "Actual:" << std::endl; |
| 1672 | printBuffer(result, actual, mLowerColorChannels.size()); |
| 1673 | } |
| 1674 | |
| 1675 | return result; |
| 1676 | } |
| 1677 | } |
| 1678 | |
| 1679 | return testing::AssertionSuccess(); |
| 1680 | } |
| 1681 | |
| 1682 | template class ExpectBetweenColors<RGBA8>; |
Corentin Wallez | a4da032 | 2018-07-18 15:18:25 +0200 | [diff] [blame] | 1683 | } // namespace detail |