diff --git a/src/dawn/fuzzers/DawnWireServerAndD3D12BackendFuzzer.cpp b/src/dawn/fuzzers/DawnWireServerAndD3D12BackendFuzzer.cpp index a2cb8e2bc3..55d26f2a88 100644 --- a/src/dawn/fuzzers/DawnWireServerAndD3D12BackendFuzzer.cpp +++ b/src/dawn/fuzzers/DawnWireServerAndD3D12BackendFuzzer.cpp @@ -25,21 +25,11 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return DawnWireServerFuzzer::Run( data, size, - [](dawn::native::Instance* instance) { - std::vector adapters = instance->GetAdapters(); - - wgpu::Device device; - for (dawn::native::Adapter adapter : adapters) { - wgpu::AdapterProperties properties; - adapter.GetProperties(&properties); - - if (properties.backendType == wgpu::BackendType::D3D12 && - properties.adapterType == wgpu::AdapterType::CPU) { - device = wgpu::Device::Acquire(adapter.CreateDevice()); - break; - } - } - return device; + [](const dawn::native::Adapter& adapter) { + wgpu::AdapterProperties properties; + adapter.GetProperties(&properties); + return properties.backendType == wgpu::BackendType::D3D12 && + properties.adapterType == wgpu::AdapterType::CPU; }, true /* supportsErrorInjection */); } diff --git a/src/dawn/fuzzers/DawnWireServerAndFrontendFuzzer.cpp b/src/dawn/fuzzers/DawnWireServerAndFrontendFuzzer.cpp index 86a2b6bc4b..0978c1e9f9 100644 --- a/src/dawn/fuzzers/DawnWireServerAndFrontendFuzzer.cpp +++ b/src/dawn/fuzzers/DawnWireServerAndFrontendFuzzer.cpp @@ -26,22 +26,10 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return DawnWireServerFuzzer::Run( data, size, - [](dawn::native::Instance* instance) { - std::vector adapters = instance->GetAdapters(); - - wgpu::Device nullDevice; - for (dawn::native::Adapter adapter : adapters) { - wgpu::AdapterProperties properties; - adapter.GetProperties(&properties); - - if (properties.backendType == wgpu::BackendType::Null) { - nullDevice = wgpu::Device::Acquire(adapter.CreateDevice()); - break; - } - } - - ASSERT(nullDevice.Get() != nullptr); - return nullDevice; + [](const dawn::native::Adapter& adapter) { + wgpu::AdapterProperties properties; + adapter.GetProperties(&properties); + return properties.backendType == wgpu::BackendType::Null; }, false /* supportsErrorInjection */); } diff --git a/src/dawn/fuzzers/DawnWireServerAndVulkanBackendFuzzer.cpp b/src/dawn/fuzzers/DawnWireServerAndVulkanBackendFuzzer.cpp index 1e55f06ff4..6b18929ea7 100644 --- a/src/dawn/fuzzers/DawnWireServerAndVulkanBackendFuzzer.cpp +++ b/src/dawn/fuzzers/DawnWireServerAndVulkanBackendFuzzer.cpp @@ -25,21 +25,12 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return DawnWireServerFuzzer::Run( data, size, - [](dawn::native::Instance* instance) { - std::vector adapters = instance->GetAdapters(); + [](const dawn::native::Adapter& adapter) { + wgpu::AdapterProperties properties; + adapter.GetProperties(&properties); - wgpu::Device device; - for (dawn::native::Adapter adapter : adapters) { - wgpu::AdapterProperties properties; - adapter.GetProperties(&properties); - - if (properties.backendType == wgpu::BackendType::Vulkan && - properties.adapterType == wgpu::AdapterType::CPU) { - device = wgpu::Device::Acquire(adapter.CreateDevice()); - break; - } - } - return device; + return properties.backendType == wgpu::BackendType::Vulkan && + properties.adapterType == wgpu::AdapterType::CPU; }, true /* supportsErrorInjection */); } diff --git a/src/dawn/fuzzers/DawnWireServerFuzzer.cpp b/src/dawn/fuzzers/DawnWireServerFuzzer.cpp index 1d325d4c27..89f1a3c682 100644 --- a/src/dawn/fuzzers/DawnWireServerFuzzer.cpp +++ b/src/dawn/fuzzers/DawnWireServerFuzzer.cpp @@ -49,8 +49,7 @@ class DevNull : public dawn::wire::CommandSerializer { std::unique_ptr sInstance; WGPUProcDeviceCreateSwapChain sOriginalDeviceCreateSwapChain = nullptr; - -bool sCommandsComplete = false; +static bool (*sAdapterSupported)(const dawn::native::Adapter&) = nullptr; WGPUSwapChain ErrorDeviceCreateSwapChain(WGPUDevice device, WGPUSurface surface, @@ -75,7 +74,7 @@ int DawnWireServerFuzzer::Initialize(int* argc, char*** argv) { int DawnWireServerFuzzer::Run(const uint8_t* data, size_t size, - MakeDeviceFn MakeDevice, + bool (*AdapterSupported)(const dawn::native::Adapter&), bool supportsErrorInjection) { // We require at least the injected error index. if (size < sizeof(uint64_t)) { @@ -96,6 +95,8 @@ int DawnWireServerFuzzer::Run(const uint8_t* data, dawn::native::InjectErrorAt(injectedErrorIndex); } + sAdapterSupported = AdapterSupported; + DawnProcTable procs = dawn::native::GetProcs(); // Swapchains receive a pointer to an implementation. The fuzzer will pass garbage in so we @@ -105,14 +106,23 @@ int DawnWireServerFuzzer::Run(const uint8_t* data, sOriginalDeviceCreateSwapChain = procs.deviceCreateSwapChain; procs.deviceCreateSwapChain = ErrorDeviceCreateSwapChain; - dawnProcSetProcs(&procs); + // Override requestAdapter to find an adapter that the fuzzer supports. + procs.instanceRequestAdapter = [](WGPUInstance cInstance, + const WGPURequestAdapterOptions* options, + WGPURequestAdapterCallback callback, void* userdata) { + std::vector adapters = sInstance->GetAdapters(); + for (dawn::native::Adapter adapter : adapters) { + if (sAdapterSupported(adapter)) { + WGPUAdapter cAdapter = adapter.Get(); + dawn::native::GetProcs().adapterReference(cAdapter); + callback(WGPURequestAdapterStatus_Success, cAdapter, nullptr, userdata); + return; + } + } + callback(WGPURequestAdapterStatus_Unavailable, nullptr, "No supported adapter.", userdata); + }; - wgpu::Device device = MakeDevice(sInstance.get()); - if (!device) { - // We should only ever fail device creation if an error was injected. - ASSERT(supportsErrorInjection); - return 0; - } + dawnProcSetProcs(&procs); DevNull devNull; dawn::wire::WireServerDescriptor serverDesc = {}; @@ -120,21 +130,11 @@ int DawnWireServerFuzzer::Run(const uint8_t* data, serverDesc.serializer = &devNull; std::unique_ptr wireServer(new dawn_wire::WireServer(serverDesc)); - wireServer->InjectDevice(device.Get(), 1, 0); - + wireServer->InjectInstance(sInstance->Get(), 1, 0); wireServer->HandleCommands(reinterpret_cast(data), size); - // Wait for all previous commands before destroying the server. - // TODO(enga): Improve this when we improve/finalize how processing events happens. - { - device.GetQueue().OnSubmittedWorkDone( - 0u, [](WGPUQueueWorkDoneStatus, void*) { sCommandsComplete = true; }, nullptr); - while (!sCommandsComplete) { - device.Tick(); - utils::USleep(100); - } - } - + // Note: Deleting the server will release all created objects. + // Deleted devices will wait for idle on destruction. wireServer = nullptr; return 0; } diff --git a/src/dawn/fuzzers/DawnWireServerFuzzer.h b/src/dawn/fuzzers/DawnWireServerFuzzer.h index 5ebc6b36e5..f076b67f81 100644 --- a/src/dawn/fuzzers/DawnWireServerFuzzer.h +++ b/src/dawn/fuzzers/DawnWireServerFuzzer.h @@ -22,17 +22,18 @@ namespace dawn::native { -class Instance; +class Adapter; } // namespace dawn::native namespace DawnWireServerFuzzer { -using MakeDeviceFn = std::function; - int Initialize(int* argc, char*** argv); -int Run(const uint8_t* data, size_t size, MakeDeviceFn MakeDevice, bool supportsErrorInjection); +int Run(const uint8_t* data, + size_t size, + bool (*AdapterSupported)(const dawn::native::Adapter&), + bool supportsErrorInjection); } // namespace DawnWireServerFuzzer diff --git a/src/dawn/tests/DawnTest.cpp b/src/dawn/tests/DawnTest.cpp index 8a931162b8..922837863c 100644 --- a/src/dawn/tests/DawnTest.cpp +++ b/src/dawn/tests/DawnTest.cpp @@ -90,6 +90,7 @@ struct MapReadUserdata { }; DawnTestEnvironment* gTestEnv = nullptr; +DawnTestBase* gCurrentTest = nullptr; template void printBuffer(testing::AssertionResult& result, const T* buffer, const size_t count) { @@ -711,14 +712,68 @@ const std::vector& DawnTestEnvironment::GetDisabledToggles() const // Implementation of DawnTest -DawnTestBase::DawnTestBase(const AdapterTestParam& param) - : mParam(param), - mWireHelper(utils::CreateWireHelper(gTestEnv->UsesWire(), gTestEnv->GetWireTraceDir())) {} +DawnTestBase::DawnTestBase(const AdapterTestParam& param) : mParam(param) { + gCurrentTest = this; + + DawnProcTable procs = dawn::native::GetProcs(); + // Override procs to provide harness-specific behavior to always select the null adapter, + // and to allow fixture-specific overriding of the test device with CreateDeviceImpl. + procs.instanceRequestAdapter = [](WGPUInstance instance, const WGPURequestAdapterOptions*, + WGPURequestAdapterCallback callback, void* userdata) { + ASSERT(gCurrentTest); + + // Find the adapter that exactly matches our adapter properties. + const auto& adapters = gTestEnv->GetInstance()->GetAdapters(); + const auto& it = std::find_if( + adapters.begin(), adapters.end(), [&](const dawn::native::Adapter& adapter) { + wgpu::AdapterProperties properties; + adapter.GetProperties(&properties); + + const auto& param = gCurrentTest->mParam; + return (param.adapterProperties.selected && + properties.deviceID == param.adapterProperties.deviceID && + properties.vendorID == param.adapterProperties.vendorID && + properties.adapterType == param.adapterProperties.adapterType && + properties.backendType == param.adapterProperties.backendType && + strcmp(properties.name, param.adapterProperties.adapterName.c_str()) == 0); + }); + ASSERT(it != adapters.end()); + gCurrentTest->mBackendAdapter = *it; + + WGPUAdapter cAdapter = it->Get(); + ASSERT(cAdapter); + dawn::native::GetProcs().adapterReference(cAdapter); + callback(WGPURequestAdapterStatus_Success, cAdapter, nullptr, userdata); + }; + + procs.adapterRequestDevice = [](WGPUAdapter adapter, const WGPUDeviceDescriptor*, + WGPURequestDeviceCallback callback, void* userdata) { + ASSERT(gCurrentTest); + + // Isolation keys may be enqueued by CreateDevice(std::string isolationKey). + // CreateDevice calls requestAdapter, so consume them there and forward them + // to CreateDeviceImpl. + std::string isolationKey; + if (!gCurrentTest->mNextIsolationKeyQueue.empty()) { + isolationKey = std::move(gCurrentTest->mNextIsolationKeyQueue.front()); + gCurrentTest->mNextIsolationKeyQueue.pop(); + } + WGPUDevice cDevice = gCurrentTest->CreateDeviceImpl(std::move(isolationKey)); + ASSERT(cDevice != nullptr); + + gCurrentTest->mLastCreatedBackendDevice = cDevice; + callback(WGPURequestDeviceStatus_Success, cDevice, nullptr, userdata); + }; + + mWireHelper = utils::CreateWireHelper(procs, gTestEnv->UsesWire(), gTestEnv->GetWireTraceDir()); +} DawnTestBase::~DawnTestBase() { mReadbackSlots.clear(); - queue = wgpu::Queue(); - device = wgpu::Device(); + queue = nullptr; + device = nullptr; + mAdapter = nullptr; + mInstance = nullptr; // D3D12's GPU-based validation will accumulate objects over time if the backend device is not // destroyed and recreated, so we reset it here. @@ -729,6 +784,8 @@ DawnTestBase::~DawnTestBase() { // Check that all devices were destructed. EXPECT_EQ(gTestEnv->GetInstance()->GetDeviceCountForTesting(), 0u); + + gCurrentTest = nullptr; } bool DawnTestBase::IsD3D12() const { @@ -895,10 +952,9 @@ const wgpu::AdapterProperties& DawnTestBase::GetAdapterProperties() const { } wgpu::SupportedLimits DawnTestBase::GetSupportedLimits() { - WGPUSupportedLimits supportedLimits; - supportedLimits.nextInChain = nullptr; - dawn::native::GetProcs().deviceGetLimits(backendDevice, &supportedLimits); - return *reinterpret_cast(&supportedLimits); + wgpu::SupportedLimits supportedLimits = {}; + device.GetLimits(&supportedLimits); + return supportedLimits; } bool DawnTestBase::SupportsFeatures(const std::vector& features) { @@ -923,10 +979,7 @@ bool DawnTestBase::SupportsFeatures(const std::vector& featur return true; } -std::pair DawnTestBase::CreateDeviceImpl(std::string isolationKey) { - // TODO(dawn:1399) Always flush wire before creating to avoid reuse of the same handle. - FlushWire(); - +WGPUDevice DawnTestBase::CreateDeviceImpl(std::string isolationKey) { // Create the device from the adapter for (const char* forceEnabledWorkaround : mParam.forceEnabledWorkarounds) { ASSERT(gTestEnv->GetInstance()->GetToggleInfo(forceEnabledWorkaround) != nullptr); @@ -977,19 +1030,38 @@ std::pair DawnTestBase::CreateDeviceImpl(std::string i togglesDesc.nextInChain = &cacheDesc; cacheDesc.isolationKey = isolationKey.c_str(); - auto devices = mWireHelper->RegisterDevice(mBackendAdapter.CreateDevice(&deviceDescriptor)); - wgpu::Device device = devices.first; + return mBackendAdapter.CreateDevice(&deviceDescriptor); +} + +wgpu::Device DawnTestBase::CreateDevice(std::string isolationKey) { + wgpu::Device apiDevice; + + // The isolation key will be consumed inside adapterRequestDevice and passed + // to CreateDeviceImpl. + mNextIsolationKeyQueue.push(std::move(isolationKey)); + + // This descriptor doesn't matter since device selection is overriden by CreateDeviceImpl. + wgpu::DeviceDescriptor deviceDesc = {}; + mAdapter.RequestDevice( + &deviceDesc, + [](WGPURequestDeviceStatus, WGPUDevice cDevice, const char*, void* userdata) { + *static_cast(userdata) = wgpu::Device::Acquire(cDevice); + }, + &apiDevice); + FlushWire(); + ASSERT(apiDevice); // Set up the mocks for uncaptured errors and device loss. The loss of the device is expected // to happen at the end of the test so at it directly. - device.SetUncapturedErrorCallback(mDeviceErrorCallback.Callback(), - mDeviceErrorCallback.MakeUserdata(device.Get())); - device.SetDeviceLostCallback(mDeviceLostCallback.Callback(), - mDeviceLostCallback.MakeUserdata(device.Get())); - EXPECT_CALL(mDeviceLostCallback, Call(WGPUDeviceLostReason_Destroyed, testing::_, device.Get())) + apiDevice.SetUncapturedErrorCallback(mDeviceErrorCallback.Callback(), + mDeviceErrorCallback.MakeUserdata(apiDevice.Get())); + apiDevice.SetDeviceLostCallback(mDeviceLostCallback.Callback(), + mDeviceLostCallback.MakeUserdata(apiDevice.Get())); + EXPECT_CALL(mDeviceLostCallback, + Call(WGPUDeviceLostReason_Destroyed, testing::_, apiDevice.Get())) .Times(testing::AtMost(1)); - device.SetLoggingCallback( + apiDevice.SetLoggingCallback( [](WGPULoggingType type, char const* message, void*) { switch (type) { case WGPULoggingType_Verbose: @@ -1008,47 +1080,38 @@ std::pair DawnTestBase::CreateDeviceImpl(std::string i }, nullptr); - return devices; -} - -wgpu::Device DawnTestBase::CreateDevice(std::string isolationKey) { - return CreateDeviceImpl(isolationKey).first; + return apiDevice; } void DawnTestBase::SetUp() { - { - // Find the adapter that exactly matches our adapter properties. - const auto& adapters = gTestEnv->GetInstance()->GetAdapters(); - const auto& it = std::find_if( - adapters.begin(), adapters.end(), [&](const dawn::native::Adapter& adapter) { - wgpu::AdapterProperties properties; - adapter.GetProperties(&properties); - - return (mParam.adapterProperties.selected && - properties.deviceID == mParam.adapterProperties.deviceID && - properties.vendorID == mParam.adapterProperties.vendorID && - properties.adapterType == mParam.adapterProperties.adapterType && - properties.backendType == mParam.adapterProperties.backendType && - strcmp(properties.name, mParam.adapterProperties.adapterName.c_str()) == 0); - }); - ASSERT(it != adapters.end()); - mBackendAdapter = *it; - } - // Setup the per-test platform. Tests can provide one by overloading CreateTestPlatform. This is // NOT a thread-safe operation and is allowed here for testing only. mTestPlatform = CreateTestPlatform(); dawn::native::FromAPI(gTestEnv->GetInstance()->Get()) ->SetPlatformForTesting(mTestPlatform.get()); + mInstance = mWireHelper->RegisterInstance(gTestEnv->GetInstance()->Get()); + std::string traceName = std::string(::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name()) + "_" + ::testing::UnitTest::GetInstance()->current_test_info()->name(); mWireHelper->BeginWireTrace(traceName.c_str()); - // Create the device from the adapter - std::tie(device, backendDevice) = CreateDeviceImpl(); - ASSERT_NE(nullptr, backendDevice); + // These options are unused since adapter selection is overriden to use the test params + wgpu::RequestAdapterOptions options = {}; + mInstance.RequestAdapter( + &options, + [](WGPURequestAdapterStatus, WGPUAdapter cAdapter, const char*, void* userdata) { + *static_cast(userdata) = wgpu::Adapter::Acquire(cAdapter); + }, + &mAdapter); + FlushWire(); + ASSERT(mAdapter); + + device = CreateDevice(); + backendDevice = mLastCreatedBackendDevice; + ASSERT(backendDevice); + ASSERT(device); queue = device.GetQueue(); diff --git a/src/dawn/tests/DawnTest.h b/src/dawn/tests/DawnTest.h index 513fb737ec..e54ff74774 100644 --- a/src/dawn/tests/DawnTest.h +++ b/src/dawn/tests/DawnTest.h @@ -16,6 +16,7 @@ #define SRC_DAWN_TESTS_DAWNTEST_H_ #include +#include #include #include #include @@ -536,18 +537,21 @@ class DawnTestBase { const wgpu::AdapterProperties& GetAdapterProperties() const; - // TODO(crbug.com/dawn/689): Use limits returned from the wire - // This is implemented here because tests need to always query - // the |backendDevice| since limits are not implemented in the wire. wgpu::SupportedLimits GetSupportedLimits(); private: utils::ScopedAutoreleasePool mObjCAutoreleasePool; AdapterTestParam mParam; std::unique_ptr mWireHelper; + wgpu::Instance mInstance; + wgpu::Adapter mAdapter; + + // Isolation keys are not exposed to the wire client. Device creation in the tests from + // the client first push the key into this queue, which is then consumed by the server. + std::queue mNextIsolationKeyQueue; // Internal device creation function for default device creation with some optional overrides. - std::pair CreateDeviceImpl(std::string isolationKey = ""); + WGPUDevice CreateDeviceImpl(std::string isolationKey); std::ostringstream& AddTextureExpectationImpl(const char* file, int line, @@ -608,6 +612,7 @@ class DawnTestBase { void ResolveExpectations(); dawn::native::Adapter mBackendAdapter; + WGPUDevice mLastCreatedBackendDevice; std::unique_ptr mTestPlatform; }; diff --git a/src/dawn/tests/unittests/validation/CopyCommandsValidationTests.cpp b/src/dawn/tests/unittests/validation/CopyCommandsValidationTests.cpp index ab77f50900..d68cead5e6 100644 --- a/src/dawn/tests/unittests/validation/CopyCommandsValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/CopyCommandsValidationTests.cpp @@ -420,13 +420,13 @@ TEST_F(CopyCommandTest_B2B, CopyWithinSameBuffer) { class CopyCommandTest_B2T : public CopyCommandTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[2] = {wgpu::FeatureName::Depth24UnormStencil8, wgpu::FeatureName::Depth32FloatStencil8}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 2; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } }; @@ -1029,13 +1029,13 @@ TEST_F(CopyCommandTest_B2T, RequiredBytesInCopyOverflow) { class CopyCommandTest_T2B : public CopyCommandTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[2] = {wgpu::FeatureName::Depth24UnormStencil8, wgpu::FeatureName::Depth32FloatStencil8}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 2; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } }; @@ -1667,13 +1667,13 @@ TEST_F(CopyCommandTest_T2B, RequiredBytesInCopyOverflow) { class CopyCommandTest_T2T : public CopyCommandTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[2] = {wgpu::FeatureName::Depth24UnormStencil8, wgpu::FeatureName::Depth32FloatStencil8}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 2; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } wgpu::TextureFormat GetCopyCompatibleFormat(wgpu::TextureFormat format) { @@ -2145,14 +2145,14 @@ TEST_F(CopyCommandTest_T2T, CopyWithinSameTexture) { class CopyCommandTest_CompressedTextureFormats : public CopyCommandTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[3] = {wgpu::FeatureName::TextureCompressionBC, wgpu::FeatureName::TextureCompressionETC2, wgpu::FeatureName::TextureCompressionASTC}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 3; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } wgpu::Texture Create2DTexture(wgpu::TextureFormat format, diff --git a/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp b/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp index 9ffba5dc88..2ed5916084 100644 --- a/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp @@ -65,13 +65,13 @@ class RequestDeviceValidationTest : public ValidationTest { // Test that requesting a device without specifying limits is valid. TEST_F(RequestDeviceValidationTest, NoRequiredLimits) { wgpu::DeviceDescriptor descriptor; - adapter.RequestDevice(&descriptor, ExpectRequestDeviceSuccess, - CheckDevice([](wgpu::Device device) { - // Check one of the default limits. - wgpu::SupportedLimits limits; - device.GetLimits(&limits); - EXPECT_EQ(limits.limits.maxBindGroups, 4u); - })); + GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceSuccess, + CheckDevice([](wgpu::Device device) { + // Check one of the default limits. + wgpu::SupportedLimits limits; + device.GetLimits(&limits); + EXPECT_EQ(limits.limits.maxBindGroups, 4u); + })); } // Test that requesting a device with the default limits is valid. @@ -79,13 +79,13 @@ TEST_F(RequestDeviceValidationTest, DefaultLimits) { wgpu::RequiredLimits limits = {}; wgpu::DeviceDescriptor descriptor; descriptor.requiredLimits = &limits; - adapter.RequestDevice(&descriptor, ExpectRequestDeviceSuccess, - CheckDevice([](wgpu::Device device) { - // Check one of the default limits. - wgpu::SupportedLimits limits; - device.GetLimits(&limits); - EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u); - })); + GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceSuccess, + CheckDevice([](wgpu::Device device) { + // Check one of the default limits. + wgpu::SupportedLimits limits; + device.GetLimits(&limits); + EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u); + })); } // Test that requesting a device where a required limit is above the maximum value. @@ -95,12 +95,12 @@ TEST_F(RequestDeviceValidationTest, HigherIsBetter) { descriptor.requiredLimits = &limits; wgpu::SupportedLimits supportedLimits; - EXPECT_TRUE(adapter.GetLimits(reinterpret_cast(&supportedLimits))); + EXPECT_TRUE(adapter.GetLimits(&supportedLimits)); // If we can support better than the default, test below the max. if (supportedLimits.limits.maxBindGroups > 4u) { limits.limits.maxBindGroups = supportedLimits.limits.maxBindGroups - 1; - adapter.RequestDevice( + GetBackendAdapter().RequestDevice( &descriptor, ExpectRequestDeviceSuccess, CheckDevice([&](wgpu::Device device) { wgpu::SupportedLimits limits; device.GetLimits(&limits); @@ -114,7 +114,7 @@ TEST_F(RequestDeviceValidationTest, HigherIsBetter) { // Test the max. limits.limits.maxBindGroups = supportedLimits.limits.maxBindGroups; - adapter.RequestDevice( + GetBackendAdapter().RequestDevice( &descriptor, ExpectRequestDeviceSuccess, CheckDevice([&](wgpu::Device device) { wgpu::SupportedLimits limits; device.GetLimits(&limits); @@ -127,18 +127,18 @@ TEST_F(RequestDeviceValidationTest, HigherIsBetter) { // Test above the max. limits.limits.maxBindGroups = supportedLimits.limits.maxBindGroups + 1; - adapter.RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr); + GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr); // Test worse than the default limits.limits.maxBindGroups = 3u; - adapter.RequestDevice(&descriptor, ExpectRequestDeviceSuccess, - CheckDevice([&](wgpu::Device device) { - wgpu::SupportedLimits limits; - device.GetLimits(&limits); + GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceSuccess, + CheckDevice([&](wgpu::Device device) { + wgpu::SupportedLimits limits; + device.GetLimits(&limits); - // Check we got the default. - EXPECT_EQ(limits.limits.maxBindGroups, 4u); - })); + // Check we got the default. + EXPECT_EQ(limits.limits.maxBindGroups, 4u); + })); } // Test that requesting a device where a required limit is below the minimum value. @@ -148,33 +148,33 @@ TEST_F(RequestDeviceValidationTest, LowerIsBetter) { descriptor.requiredLimits = &limits; wgpu::SupportedLimits supportedLimits; - EXPECT_TRUE(adapter.GetLimits(reinterpret_cast(&supportedLimits))); + EXPECT_TRUE(adapter.GetLimits(&supportedLimits)); // Test below the min. limits.limits.minUniformBufferOffsetAlignment = supportedLimits.limits.minUniformBufferOffsetAlignment / 2; - adapter.RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr); + GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr); // Test the min. limits.limits.minUniformBufferOffsetAlignment = supportedLimits.limits.minUniformBufferOffsetAlignment; - adapter.RequestDevice(&descriptor, ExpectRequestDeviceSuccess, - CheckDevice([&](wgpu::Device device) { - wgpu::SupportedLimits limits; - device.GetLimits(&limits); + GetBackendAdapter().RequestDevice( + &descriptor, ExpectRequestDeviceSuccess, CheckDevice([&](wgpu::Device device) { + wgpu::SupportedLimits limits; + device.GetLimits(&limits); - // Check we got exactly the request. - EXPECT_EQ(limits.limits.minUniformBufferOffsetAlignment, - supportedLimits.limits.minUniformBufferOffsetAlignment); - // Check another default limit. - EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u); - })); + // Check we got exactly the request. + EXPECT_EQ(limits.limits.minUniformBufferOffsetAlignment, + supportedLimits.limits.minUniformBufferOffsetAlignment); + // Check another default limit. + EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u); + })); // IF we can support better than the default, test above the min. if (supportedLimits.limits.minUniformBufferOffsetAlignment > 256u) { limits.limits.minUniformBufferOffsetAlignment = supportedLimits.limits.minUniformBufferOffsetAlignment * 2; - adapter.RequestDevice( + GetBackendAdapter().RequestDevice( &descriptor, ExpectRequestDeviceSuccess, CheckDevice([&](wgpu::Device device) { wgpu::SupportedLimits limits; device.GetLimits(&limits); @@ -189,14 +189,14 @@ TEST_F(RequestDeviceValidationTest, LowerIsBetter) { // Test worse than the default limits.limits.minUniformBufferOffsetAlignment = 2u * 256u; - adapter.RequestDevice(&descriptor, ExpectRequestDeviceSuccess, - CheckDevice([&](wgpu::Device device) { - wgpu::SupportedLimits limits; - device.GetLimits(&limits); + GetBackendAdapter().RequestDevice( + &descriptor, ExpectRequestDeviceSuccess, CheckDevice([&](wgpu::Device device) { + wgpu::SupportedLimits limits; + device.GetLimits(&limits); - // Check we got the default. - EXPECT_EQ(limits.limits.minUniformBufferOffsetAlignment, 256u); - })); + // Check we got the default. + EXPECT_EQ(limits.limits.minUniformBufferOffsetAlignment, 256u); + })); } // Test that it is an error to request limits with an invalid chained struct @@ -207,7 +207,7 @@ TEST_F(RequestDeviceValidationTest, InvalidChainedStruct) { wgpu::DeviceDescriptor descriptor; descriptor.requiredLimits = &limits; - adapter.RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr); + GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr); } class DeviceTickValidationTest : public ValidationTest {}; diff --git a/src/dawn/tests/unittests/validation/InternalUsageValidationTests.cpp b/src/dawn/tests/unittests/validation/InternalUsageValidationTests.cpp index 623697d292..f9a25ab417 100644 --- a/src/dawn/tests/unittests/validation/InternalUsageValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/InternalUsageValidationTests.cpp @@ -64,12 +64,12 @@ TEST_F(InternalUsageValidationDisabledTest, CommandEncoderDescriptorRequiresFeat } class TextureInternalUsageValidationTest : public ValidationTest { - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DawnInternalUsages}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 1; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } }; diff --git a/src/dawn/tests/unittests/validation/LabelTests.cpp b/src/dawn/tests/unittests/validation/LabelTests.cpp index 3bba45f50d..7b70db6e95 100644 --- a/src/dawn/tests/unittests/validation/LabelTests.cpp +++ b/src/dawn/tests/unittests/validation/LabelTests.cpp @@ -18,10 +18,14 @@ #include "dawn/utils/ComboRenderPipelineDescriptor.h" #include "dawn/utils/WGPUHelpers.h" -class LabelTest : public ValidationTest {}; +class LabelTest : public ValidationTest { + void SetUp() override { + ValidationTest::SetUp(); + DAWN_SKIP_TEST_IF(UsesWire()); + } +}; TEST_F(LabelTest, BindGroup) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {}); @@ -55,7 +59,6 @@ TEST_F(LabelTest, BindGroup) { } TEST_F(LabelTest, BindGroupLayout) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::BindGroupLayoutDescriptor descriptor = {}; @@ -87,7 +90,6 @@ TEST_F(LabelTest, BindGroupLayout) { } TEST_F(LabelTest, Buffer) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::BufferDescriptor descriptor; descriptor.size = 4; @@ -118,7 +120,6 @@ TEST_F(LabelTest, Buffer) { } TEST_F(LabelTest, CommandBuffer) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::CommandBufferDescriptor descriptor; @@ -150,7 +151,6 @@ TEST_F(LabelTest, CommandBuffer) { } TEST_F(LabelTest, CommandEncoder) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::CommandEncoderDescriptor descriptor; @@ -179,7 +179,6 @@ TEST_F(LabelTest, CommandEncoder) { } TEST_F(LabelTest, ComputePassEncoder) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); @@ -213,7 +212,6 @@ TEST_F(LabelTest, ComputePassEncoder) { } TEST_F(LabelTest, ExternalTexture) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::TextureDescriptor textureDescriptor; textureDescriptor.size.width = 1; @@ -260,7 +258,6 @@ TEST_F(LabelTest, ExternalTexture) { } TEST_F(LabelTest, PipelineLayout) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {}); @@ -324,13 +321,13 @@ TEST_F(LabelTest, QuerySet) { } TEST_F(LabelTest, Queue) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; // The label should be empty if one was not set. { wgpu::DeviceDescriptor descriptor; - wgpu::Device labelDevice = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); + wgpu::Device labelDevice = + wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor)); std::string readbackLabel = dawn::native::GetObjectLabelForTesting(labelDevice.GetQueue().Get()); ASSERT_TRUE(readbackLabel.empty()); @@ -339,7 +336,8 @@ TEST_F(LabelTest, Queue) { // Test setting a label through API { wgpu::DeviceDescriptor descriptor; - wgpu::Device labelDevice = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); + wgpu::Device labelDevice = + wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor)); labelDevice.GetQueue().SetLabel(label.c_str()); std::string readbackLabel = dawn::native::GetObjectLabelForTesting(labelDevice.GetQueue().Get()); @@ -350,7 +348,8 @@ TEST_F(LabelTest, Queue) { { wgpu::DeviceDescriptor descriptor; descriptor.defaultQueue.label = label.c_str(); - wgpu::Device labelDevice = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); + wgpu::Device labelDevice = + wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor)); std::string readbackLabel = dawn::native::GetObjectLabelForTesting(labelDevice.GetQueue().Get()); ASSERT_EQ(label, readbackLabel); @@ -358,7 +357,6 @@ TEST_F(LabelTest, Queue) { } TEST_F(LabelTest, RenderBundleEncoder) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; utils::ComboRenderBundleEncoderDescriptor descriptor = {}; @@ -390,7 +388,6 @@ TEST_F(LabelTest, RenderBundleEncoder) { } TEST_F(LabelTest, RenderPassEncoder) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); @@ -430,7 +427,6 @@ TEST_F(LabelTest, RenderPassEncoder) { } TEST_F(LabelTest, Sampler) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::SamplerDescriptor descriptor; @@ -459,7 +455,6 @@ TEST_F(LabelTest, Sampler) { } TEST_F(LabelTest, Texture) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::TextureDescriptor descriptor; descriptor.size.width = 1; @@ -496,7 +491,6 @@ TEST_F(LabelTest, Texture) { } TEST_F(LabelTest, TextureView) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::TextureDescriptor descriptor; descriptor.size.width = 1; @@ -536,7 +530,6 @@ TEST_F(LabelTest, TextureView) { } TEST_F(LabelTest, RenderPipeline) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"( @@ -578,7 +571,6 @@ TEST_F(LabelTest, RenderPipeline) { } TEST_F(LabelTest, ComputePipeline) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; wgpu::ShaderModule computeModule = utils::CreateShaderModule(device, R"( @@ -615,7 +607,6 @@ TEST_F(LabelTest, ComputePipeline) { } TEST_F(LabelTest, ShaderModule) { - DAWN_SKIP_TEST_IF(UsesWire()); std::string label = "test"; const char* source = R"( diff --git a/src/dawn/tests/unittests/validation/MultipleDeviceTests.cpp b/src/dawn/tests/unittests/validation/MultipleDeviceTests.cpp index 2f1c515e4f..829e883282 100644 --- a/src/dawn/tests/unittests/validation/MultipleDeviceTests.cpp +++ b/src/dawn/tests/unittests/validation/MultipleDeviceTests.cpp @@ -27,7 +27,7 @@ class MultipleDeviceTest : public ValidationTest {}; // Test that it is invalid to submit a command buffer created on a different device. TEST_F(MultipleDeviceTest, ValidatesSameDevice) { - wgpu::Device device2 = RegisterDevice(CreateTestDevice()); + wgpu::Device device2 = RequestDeviceSync(wgpu::DeviceDescriptor{}); wgpu::CommandBuffer commandBuffer = device2.CreateCommandEncoder().Finish(); ASSERT_DEVICE_ERROR(device.GetQueue().Submit(1, &commandBuffer)); @@ -66,7 +66,7 @@ TEST_F(MultipleDeviceTest, ValidatesSameDeviceCreatePipelineAsync) { // CreateComputePipelineAsync errors if the shader module is created on a different device. { - wgpu::Device device2 = RegisterDevice(CreateTestDevice()); + wgpu::Device device2 = RequestDeviceSync(wgpu::DeviceDescriptor{}); wgpu::ShaderModule shaderModule = device2.CreateShaderModule(&shaderModuleDesc); wgpu::ComputePipelineDescriptor pipelineDesc = {}; diff --git a/src/dawn/tests/unittests/validation/QueryValidationTests.cpp b/src/dawn/tests/unittests/validation/QueryValidationTests.cpp index bc3b7fed91..04899adb11 100644 --- a/src/dawn/tests/unittests/validation/QueryValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/QueryValidationTests.cpp @@ -111,7 +111,7 @@ TEST_F(OcclusionQueryValidationTest, InvalidOcclusionQuerySet) { // Fail to begin render pass if the occlusionQuerySet is created from other device { - wgpu::Device otherDevice = RegisterDevice(adapter.CreateDevice()); + wgpu::Device otherDevice = RequestDeviceSync(wgpu::DeviceDescriptor{}); wgpu::QuerySet occlusionQuerySetOnOther = CreateQuerySet(otherDevice, wgpu::QueryType::Occlusion, 2); renderPass.occlusionQuerySet = occlusionQuerySetOnOther; @@ -225,7 +225,7 @@ TEST_F(OcclusionQueryValidationTest, InvalidBeginAndEnd) { class TimestampQueryValidationTest : public QuerySetValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::TimestampQuery}; descriptor.requiredFeatures = requiredFeatures; @@ -237,7 +237,7 @@ class TimestampQueryValidationTest : public QuerySetValidationTest { togglesDesc.forceDisabledToggles = forceDisabledToggles; togglesDesc.forceDisabledTogglesCount = 1; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } void EncodeRenderPassWithTimestampWrites( @@ -324,7 +324,7 @@ TEST_F(TimestampQueryValidationTest, TimestampWritesOnComputePass) { // Fail to write timestamps to a query set created from another device { - wgpu::Device otherDevice = RegisterDevice(adapter.CreateDevice()); + wgpu::Device otherDevice = RequestDeviceSync(wgpu::DeviceDescriptor{}); wgpu::QuerySet querySetFromOtherDevice = CreateQuerySet(otherDevice, wgpu::QueryType::Timestamp, 2); @@ -408,7 +408,7 @@ TEST_F(TimestampQueryValidationTest, TimestampWritesOnRenderPass) { // Fail to write timestamps to a query set created from another device { - wgpu::Device otherDevice = RegisterDevice(adapter.CreateDevice()); + wgpu::Device otherDevice = RequestDeviceSync(wgpu::DeviceDescriptor{}); wgpu::QuerySet querySetFromOtherDevice = CreateQuerySet(otherDevice, wgpu::QueryType::Timestamp, 2); @@ -640,7 +640,7 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnRenderPassEncoder) { class PipelineStatisticsQueryValidationTest : public QuerySetValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::PipelineStatisticsQuery}; descriptor.requiredFeatures = requiredFeatures; @@ -654,7 +654,7 @@ class PipelineStatisticsQueryValidationTest : public QuerySetValidationTest { togglesDesc.forceDisabledToggles = forceDisabledToggles; togglesDesc.forceDisabledTogglesCount = 1; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } }; @@ -793,7 +793,7 @@ TEST_F(ResolveQuerySetValidationTest, ResolveToInvalidBufferAndOffset) { // Fail to resolve query set to a buffer created from another device { - wgpu::Device otherDevice = RegisterDevice(adapter.CreateDevice()); + wgpu::Device otherDevice = RequestDeviceSync(wgpu::DeviceDescriptor{}); wgpu::Buffer bufferOnOther = CreateBuffer(otherDevice, kBufferSize, wgpu::BufferUsage::QueryResolve); wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); diff --git a/src/dawn/tests/unittests/validation/QueueWriteTextureValidationTests.cpp b/src/dawn/tests/unittests/validation/QueueWriteTextureValidationTests.cpp index b5fe723367..bb098fd8a3 100644 --- a/src/dawn/tests/unittests/validation/QueueWriteTextureValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/QueueWriteTextureValidationTests.cpp @@ -535,14 +535,14 @@ TEST_F(QueueWriteTextureValidationTest, WriteToStencilAspect) { class WriteTextureTest_CompressedTextureFormats : public QueueWriteTextureValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[3] = {wgpu::FeatureName::TextureCompressionBC, wgpu::FeatureName::TextureCompressionETC2, wgpu::FeatureName::TextureCompressionASTC}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 3; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } wgpu::Texture Create2DTexture(wgpu::TextureFormat format, diff --git a/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp b/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp index 203599bf29..1810495307 100644 --- a/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp @@ -1267,12 +1267,12 @@ TEST_F(RenderPipelineValidationTest, BindingsFromCorrectEntryPoint) { class DepthClampingValidationTest : public RenderPipelineValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DepthClamping}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 1; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } }; diff --git a/src/dawn/tests/unittests/validation/TextureValidationTests.cpp b/src/dawn/tests/unittests/validation/TextureValidationTests.cpp index 3de9c27380..ffac5ada70 100644 --- a/src/dawn/tests/unittests/validation/TextureValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/TextureValidationTests.cpp @@ -698,12 +698,12 @@ TEST_F(TextureValidationTest, UseASTCFormatWithoutEnablingFeature) { class D24S8TextureFormatsValidationTests : public TextureValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth24UnormStencil8}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 1; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } }; @@ -720,12 +720,12 @@ TEST_F(D24S8TextureFormatsValidationTests, DepthStencilFormatsFor3D) { class D32S8TextureFormatsValidationTests : public TextureValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 1; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } }; @@ -742,7 +742,7 @@ TEST_F(D32S8TextureFormatsValidationTests, DepthStencilFormatsFor3D) { class CompressedTextureFormatsValidationTests : public TextureValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[3] = {wgpu::FeatureName::TextureCompressionBC, wgpu::FeatureName::TextureCompressionETC2, @@ -758,7 +758,7 @@ class CompressedTextureFormatsValidationTests : public TextureValidationTest { descriptor.nextInChain = &togglesDesc; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } wgpu::TextureDescriptor CreateDefaultTextureDescriptor() { diff --git a/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp b/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp index 56c543d7c7..9ecd9c1dba 100644 --- a/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp @@ -925,12 +925,12 @@ TEST_F(TextureViewValidationTest, AspectMustExist) { class D24S8TextureViewValidationTests : public ValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth24UnormStencil8}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 1; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } }; @@ -971,12 +971,12 @@ TEST_F(D24S8TextureViewValidationTests, TextureViewFormatCompatibility) { class D32S8TextureViewValidationTests : public ValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 1; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } }; diff --git a/src/dawn/tests/unittests/validation/ToggleValidationTests.cpp b/src/dawn/tests/unittests/validation/ToggleValidationTests.cpp index 677f6e2253..51514281d9 100644 --- a/src/dawn/tests/unittests/validation/ToggleValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/ToggleValidationTests.cpp @@ -30,7 +30,7 @@ TEST_F(ToggleValidationTest, QueryToggleInfo) { // Query with a valid toggle name { const char* kValidToggleName = "emulate_store_and_msaa_resolve"; - const dawn::native::ToggleInfo* toggleInfo = instance->GetToggleInfo(kValidToggleName); + const dawn::native::ToggleInfo* toggleInfo = GetToggleInfo(kValidToggleName); ASSERT_NE(nullptr, toggleInfo); ASSERT_NE(nullptr, toggleInfo->name); ASSERT_NE(nullptr, toggleInfo->description); @@ -40,7 +40,7 @@ TEST_F(ToggleValidationTest, QueryToggleInfo) { // Query with an invalid toggle name { const char* kInvalidToggleName = "!@#$%^&*"; - const dawn::native::ToggleInfo* toggleInfo = instance->GetToggleInfo(kInvalidToggleName); + const dawn::native::ToggleInfo* toggleInfo = GetToggleInfo(kInvalidToggleName); ASSERT_EQ(nullptr, toggleInfo); } } @@ -56,7 +56,8 @@ TEST_F(ToggleValidationTest, OverrideToggleUsage) { togglesDesc.forceEnabledToggles = &kValidToggleName; togglesDesc.forceEnabledTogglesCount = 1; - wgpu::Device deviceWithToggle = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); + wgpu::Device deviceWithToggle = + wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor)); std::vector toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle.Get()); bool validToggleExists = false; for (const char* toggle : toggleNames) { @@ -76,7 +77,8 @@ TEST_F(ToggleValidationTest, OverrideToggleUsage) { togglesDesc.forceEnabledToggles = &kInvalidToggleName; togglesDesc.forceEnabledTogglesCount = 1; - wgpu::Device deviceWithToggle = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); + wgpu::Device deviceWithToggle = + wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor)); std::vector toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle.Get()); bool InvalidToggleExists = false; for (const char* toggle : toggleNames) { @@ -96,7 +98,8 @@ TEST_F(ToggleValidationTest, TurnOffVsyncWithToggle) { togglesDesc.forceEnabledToggles = &kValidToggleName; togglesDesc.forceEnabledTogglesCount = 1; - wgpu::Device deviceWithToggle = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); + wgpu::Device deviceWithToggle = + wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor)); std::vector toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle.Get()); bool validToggleExists = false; for (const char* toggle : toggleNames) { diff --git a/src/dawn/tests/unittests/validation/UnsafeAPIValidationTests.cpp b/src/dawn/tests/unittests/validation/UnsafeAPIValidationTests.cpp index 95b56458fb..712e2be1fa 100644 --- a/src/dawn/tests/unittests/validation/UnsafeAPIValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/UnsafeAPIValidationTests.cpp @@ -26,14 +26,14 @@ using testing::HasSubstr; class UnsafeAPIValidationTest : public ValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::DawnTogglesDeviceDescriptor togglesDesc; descriptor.nextInChain = &togglesDesc; const char* toggle = "disallow_unsafe_apis"; togglesDesc.forceEnabledToggles = &toggle; togglesDesc.forceEnabledTogglesCount = 1; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } }; @@ -79,7 +79,7 @@ TEST_F(UnsafeAPIValidationTest, PipelineOverridableConstants) { class UnsafeQueryAPIValidationTest : public ValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[2] = {wgpu::FeatureName::PipelineStatisticsQuery, wgpu::FeatureName::TimestampQuery}; @@ -92,7 +92,7 @@ class UnsafeQueryAPIValidationTest : public ValidationTest { togglesDesc.forceEnabledToggles = &toggle; togglesDesc.forceEnabledTogglesCount = 1; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } }; diff --git a/src/dawn/tests/unittests/validation/ValidationTest.cpp b/src/dawn/tests/unittests/validation/ValidationTest.cpp index 14d5372633..1127fa6981 100644 --- a/src/dawn/tests/unittests/validation/ValidationTest.cpp +++ b/src/dawn/tests/unittests/validation/ValidationTest.cpp @@ -30,6 +30,7 @@ bool gUseWire = false; // NOLINTNEXTLINE(runtime/string) std::string gWireTraceDir = ""; std::unique_ptr gToggleParser = nullptr; +static ValidationTest* gCurrentTest = nullptr; } // namespace @@ -79,48 +80,86 @@ void InitDawnValidationTestEnvironment(int argc, char** argv) { } } -ValidationTest::ValidationTest() - : mWireHelper(utils::CreateWireHelper(gUseWire, gWireTraceDir.c_str())) {} +ValidationTest::ValidationTest() { + gCurrentTest = this; + + DawnProcTable procs = dawn::native::GetProcs(); + // Override procs to provide harness-specific behavior to always select the null adapter, + // and to allow fixture-specific overriding of the test device with CreateTestDevice. + procs.instanceRequestAdapter = [](WGPUInstance instance, const WGPURequestAdapterOptions*, + WGPURequestAdapterCallback callback, void* userdata) { + ASSERT(gCurrentTest); + std::vector adapters = gCurrentTest->mDawnInstance->GetAdapters(); + // Validation tests run against the null backend, find the corresponding adapter + for (auto& adapter : adapters) { + wgpu::AdapterProperties adapterProperties; + adapter.GetProperties(&adapterProperties); + + if (adapterProperties.backendType == wgpu::BackendType::Null) { + gCurrentTest->mBackendAdapter = adapter; + WGPUAdapter cAdapter = adapter.Get(); + ASSERT(cAdapter); + dawn::native::GetProcs().adapterReference(cAdapter); + callback(WGPURequestAdapterStatus_Success, cAdapter, nullptr, userdata); + return; + } + } + UNREACHABLE(); + }; + + procs.adapterRequestDevice = [](WGPUAdapter adapter, const WGPUDeviceDescriptor*, + WGPURequestDeviceCallback callback, void* userdata) { + ASSERT(gCurrentTest); + WGPUDevice cDevice = gCurrentTest->CreateTestDevice( + dawn::native::Adapter(reinterpret_cast(adapter))); + ASSERT(cDevice != nullptr); + gCurrentTest->mLastCreatedBackendDevice = cDevice; + callback(WGPURequestDeviceStatus_Success, cDevice, nullptr, userdata); + }; + + mWireHelper = utils::CreateWireHelper(procs, gUseWire, gWireTraceDir.c_str()); +} void ValidationTest::SetUp() { - instance = std::make_unique(); - instance->DiscoverDefaultAdapters(); - - std::vector adapters = instance->GetAdapters(); - - // Validation tests run against the null backend, find the corresponding adapter - bool foundNullAdapter = false; - for (auto& currentAdapter : adapters) { - wgpu::AdapterProperties adapterProperties; - currentAdapter.GetProperties(&adapterProperties); - - if (adapterProperties.backendType == wgpu::BackendType::Null) { - adapter = currentAdapter; - foundNullAdapter = true; - break; - } - } - - ASSERT(foundNullAdapter); - - std::tie(device, backendDevice) = mWireHelper->RegisterDevice(CreateTestDevice()); - device.SetUncapturedErrorCallback(ValidationTest::OnDeviceError, this); - device.SetDeviceLostCallback(ValidationTest::OnDeviceLost, this); + mDawnInstance = std::make_unique(); + mDawnInstance->DiscoverDefaultAdapters(); + mInstance = mWireHelper->RegisterInstance(mDawnInstance->Get()); std::string traceName = std::string(::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name()) + "_" + ::testing::UnitTest::GetInstance()->current_test_info()->name(); mWireHelper->BeginWireTrace(traceName.c_str()); + + // These options are unused since validation tests always select the null adapter + wgpu::RequestAdapterOptions options = {}; + mInstance.RequestAdapter( + &options, + [](WGPURequestAdapterStatus, WGPUAdapter cAdapter, const char*, void* userdata) { + *static_cast(userdata) = wgpu::Adapter::Acquire(cAdapter); + }, + &adapter); + FlushWire(); + ASSERT(adapter); + + device = RequestDeviceSync(wgpu::DeviceDescriptor{}); + backendDevice = mLastCreatedBackendDevice; + + device.SetUncapturedErrorCallback(ValidationTest::OnDeviceError, this); + device.SetDeviceLostCallback(ValidationTest::OnDeviceLost, this); } ValidationTest::~ValidationTest() { - // We need to destroy Dawn objects before setting the procs to null otherwise the dawn*Release - // will call a nullptr - device = wgpu::Device(); + // We need to destroy Dawn objects before the wire helper which sets procs to null otherwise the + // dawn*Release will call a nullptr + device = nullptr; + adapter = nullptr; + mInstance = nullptr; mWireHelper.reset(); // Check that all devices were destructed. - EXPECT_EQ(instance->GetDeviceCountForTesting(), 0u); + EXPECT_EQ(mDawnInstance->GetDeviceCountForTesting(), 0u); + + gCurrentTest = nullptr; } void ValidationTest::TearDown() { @@ -159,10 +198,6 @@ void ValidationTest::ExpectDeviceDestruction() { mExpectDestruction = true; } -wgpu::Device ValidationTest::RegisterDevice(WGPUDevice backendDevice) { - return mWireHelper->RegisterDevice(backendDevice).first; -} - bool ValidationTest::UsesWire() const { return gUseWire; } @@ -190,6 +225,10 @@ void ValidationTest::WaitForAllOperations(const wgpu::Device& device) { FlushWire(); } +const dawn::native::ToggleInfo* ValidationTest::GetToggleInfo(const char* name) const { + return mDawnInstance->GetToggleInfo(name); +} + bool ValidationTest::HasToggleEnabled(const char* toggle) const { auto toggles = dawn::native::GetTogglesUsed(backendDevice); return std::find_if(toggles.begin(), toggles.end(), [toggle](const char* name) { @@ -197,14 +236,33 @@ bool ValidationTest::HasToggleEnabled(const char* toggle) const { }) != toggles.end(); } -wgpu::SupportedLimits ValidationTest::GetSupportedLimits() { - WGPUSupportedLimits supportedLimits; - supportedLimits.nextInChain = nullptr; - dawn::native::GetProcs().deviceGetLimits(backendDevice, &supportedLimits); - return *reinterpret_cast(&supportedLimits); +wgpu::SupportedLimits ValidationTest::GetSupportedLimits() const { + wgpu::SupportedLimits supportedLimits = {}; + device.GetLimits(&supportedLimits); + return supportedLimits; } -WGPUDevice ValidationTest::CreateTestDevice() { +wgpu::Device ValidationTest::RequestDeviceSync(const wgpu::DeviceDescriptor& deviceDesc) { + ASSERT(adapter); + + wgpu::Device apiDevice; + adapter.RequestDevice( + &deviceDesc, + [](WGPURequestDeviceStatus, WGPUDevice cDevice, const char*, void* userdata) { + *static_cast(userdata) = wgpu::Device::Acquire(cDevice); + }, + &apiDevice); + FlushWire(); + + ASSERT(apiDevice); + return apiDevice; +} + +dawn::native::Adapter& ValidationTest::GetBackendAdapter() { + return mBackendAdapter; +} + +WGPUDevice ValidationTest::CreateTestDevice(dawn::native::Adapter dawnAdapter) { // Disabled disallowing unsafe APIs so we can test them. std::vector forceEnabledToggles; std::vector forceDisabledToggles = {"disallow_unsafe_apis"}; @@ -226,7 +284,7 @@ WGPUDevice ValidationTest::CreateTestDevice() { togglesDesc.forceDisabledToggles = forceDisabledToggles.data(); togglesDesc.forceDisabledTogglesCount = forceDisabledToggles.size(); - return adapter.CreateDevice(&deviceDescriptor); + return dawnAdapter.CreateDevice(&deviceDescriptor); } // static diff --git a/src/dawn/tests/unittests/validation/ValidationTest.h b/src/dawn/tests/unittests/validation/ValidationTest.h index f373b28fa2..bc064cf43e 100644 --- a/src/dawn/tests/unittests/validation/ValidationTest.h +++ b/src/dawn/tests/unittests/validation/ValidationTest.h @@ -108,8 +108,6 @@ class ValidationTest : public testing::Test { void ExpectDeviceDestruction(); - wgpu::Device RegisterDevice(WGPUDevice backendDevice); - bool UsesWire() const; void FlushWire(); @@ -129,25 +127,28 @@ class ValidationTest : public testing::Test { wgpu::RenderPassColorAttachment mColorAttachment; }; + const dawn::native::ToggleInfo* GetToggleInfo(const char* name) const; bool HasToggleEnabled(const char* toggle) const; - - // TODO(crbug.com/dawn/689): Use limits returned from the wire - // This is implemented here because tests need to always query - // the |backendDevice| since limits are not implemented in the wire. - wgpu::SupportedLimits GetSupportedLimits(); + wgpu::SupportedLimits GetSupportedLimits() const; protected: - virtual WGPUDevice CreateTestDevice(); + dawn::native::Adapter& GetBackendAdapter(); + virtual WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter); + + wgpu::Device RequestDeviceSync(const wgpu::DeviceDescriptor& deviceDesc); - std::unique_ptr instance; - dawn::native::Adapter adapter; wgpu::Device device; + wgpu::Adapter adapter; WGPUDevice backendDevice; size_t mLastWarningCount = 0; private: + std::unique_ptr mDawnInstance; + wgpu::Instance mInstance; + dawn::native::Adapter mBackendAdapter; std::unique_ptr mWireHelper; + WGPUDevice mLastCreatedBackendDevice; static void OnDeviceError(WGPUErrorType type, const char* message, void* userdata); static void OnDeviceLost(WGPUDeviceLostReason reason, const char* message, void* userdata); diff --git a/src/dawn/tests/unittests/validation/VideoViewsValidationTests.cpp b/src/dawn/tests/unittests/validation/VideoViewsValidationTests.cpp index 6075b94d10..e566958484 100644 --- a/src/dawn/tests/unittests/validation/VideoViewsValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/VideoViewsValidationTests.cpp @@ -21,12 +21,12 @@ namespace { class VideoViewsValidation : public ValidationTest { protected: - WGPUDevice CreateTestDevice() override { + WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override { wgpu::DeviceDescriptor descriptor; wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DawnMultiPlanarFormats}; descriptor.requiredFeatures = requiredFeatures; descriptor.requiredFeaturesCount = 1; - return adapter.CreateDevice(&descriptor); + return dawnAdapter.CreateDevice(&descriptor); } wgpu::Texture CreateVideoTextureForTest(wgpu::TextureFormat format, wgpu::TextureUsage usage) { diff --git a/src/dawn/utils/WireHelper.cpp b/src/dawn/utils/WireHelper.cpp index c00006f3ad..609e8ff9d3 100644 --- a/src/dawn/utils/WireHelper.cpp +++ b/src/dawn/utils/WireHelper.cpp @@ -78,11 +78,11 @@ class WireServerTraceLayer : public dawn::wire::CommandHandler { class WireHelperDirect : public WireHelper { public: - WireHelperDirect() { dawnProcSetProcs(&dawn::native::GetProcs()); } + explicit WireHelperDirect(const DawnProcTable& procs) { dawnProcSetProcs(&procs); } - std::pair RegisterDevice(WGPUDevice backendDevice) override { - ASSERT(backendDevice != nullptr); - return std::make_pair(wgpu::Device::Acquire(backendDevice), backendDevice); + wgpu::Instance RegisterInstance(WGPUInstance backendInstance) override { + ASSERT(backendInstance != nullptr); + return wgpu::Instance(backendInstance); } void BeginWireTrace(const char* name) override {} @@ -94,12 +94,12 @@ class WireHelperDirect : public WireHelper { class WireHelperProxy : public WireHelper { public: - explicit WireHelperProxy(const char* wireTraceDir) { + explicit WireHelperProxy(const char* wireTraceDir, const DawnProcTable& procs) { mC2sBuf = std::make_unique(); mS2cBuf = std::make_unique(); dawn::wire::WireServerDescriptor serverDesc = {}; - serverDesc.procs = &dawn::native::GetProcs(); + serverDesc.procs = &procs; serverDesc.serializer = mS2cBuf.get(); mWireServer.reset(new dawn::wire::WireServer(serverDesc)); @@ -118,14 +118,13 @@ class WireHelperProxy : public WireHelper { dawnProcSetProcs(&dawn::wire::client::GetProcs()); } - std::pair RegisterDevice(WGPUDevice backendDevice) override { - ASSERT(backendDevice != nullptr); + wgpu::Instance RegisterInstance(WGPUInstance backendInstance) override { + ASSERT(backendInstance != nullptr); - auto reservation = mWireClient->ReserveDevice(); - mWireServer->InjectDevice(backendDevice, reservation.id, reservation.generation); - dawn::native::GetProcs().deviceRelease(backendDevice); + auto reservation = mWireClient->ReserveInstance(); + mWireServer->InjectInstance(backendInstance, reservation.id, reservation.generation); - return std::make_pair(wgpu::Device::Acquire(reservation.device), backendDevice); + return wgpu::Instance::Acquire(reservation.instance); } void BeginWireTrace(const char* name) override { @@ -148,11 +147,13 @@ class WireHelperProxy : public WireHelper { } // anonymous namespace -std::unique_ptr CreateWireHelper(bool useWire, const char* wireTraceDir) { +std::unique_ptr CreateWireHelper(const DawnProcTable& procs, + bool useWire, + const char* wireTraceDir) { if (useWire) { - return std::unique_ptr(new WireHelperProxy(wireTraceDir)); + return std::unique_ptr(new WireHelperProxy(wireTraceDir, procs)); } else { - return std::unique_ptr(new WireHelperDirect()); + return std::unique_ptr(new WireHelperDirect(procs)); } } diff --git a/src/dawn/utils/WireHelper.h b/src/dawn/utils/WireHelper.h index 73c45ad679..a81b919e12 100644 --- a/src/dawn/utils/WireHelper.h +++ b/src/dawn/utils/WireHelper.h @@ -27,10 +27,11 @@ class WireHelper { public: virtual ~WireHelper(); - // Registers the device on the wire, if present. - // Returns a pair of the client device and backend device. - // The function should take ownership of |backendDevice|. - virtual std::pair RegisterDevice(WGPUDevice backendDevice) = 0; + // Registers the instance on the wire, if present. + // Returns the wgpu::Instance which is the client instance on the wire, and + // the backend instance without the wire. + // The function should not take ownership of |backendInstance|. + virtual wgpu::Instance RegisterInstance(WGPUInstance backendInstance) = 0; virtual void BeginWireTrace(const char* name) = 0; @@ -38,7 +39,9 @@ class WireHelper { virtual bool FlushServer() = 0; }; -std::unique_ptr CreateWireHelper(bool useWire, const char* wireTraceDir = nullptr); +std::unique_ptr CreateWireHelper(const DawnProcTable& procs, + bool useWire, + const char* wireTraceDir = nullptr); } // namespace utils