diff --git a/include/dawn/native/DawnNative.h b/include/dawn/native/DawnNative.h index ad4e6105e5..9c60409996 100644 --- a/include/dawn/native/DawnNative.h +++ b/include/dawn/native/DawnNative.h @@ -170,6 +170,8 @@ class DAWN_NATIVE_EXPORT Instance { // TODO(dawn:1374) Deprecate this once it is passed via the descriptor. void SetPlatform(dawn::platform::Platform* platform); + uint64_t GetDeviceCountForTesting() const; + // Returns the underlying WGPUInstance object. WGPUInstance Get() const; diff --git a/src/dawn/native/DawnNative.cpp b/src/dawn/native/DawnNative.cpp index 69296ef27c..00b15cdd83 100644 --- a/src/dawn/native/DawnNative.cpp +++ b/src/dawn/native/DawnNative.cpp @@ -244,6 +244,10 @@ void Instance::SetPlatform(dawn::platform::Platform* platform) { mImpl->SetPlatform(platform); } +uint64_t Instance::GetDeviceCountForTesting() const { + return mImpl->GetDeviceCountForTesting(); +} + WGPUInstance Instance::Get() const { return ToAPI(mImpl); } diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp index 26d5bb60a4..1f11514f38 100644 --- a/src/dawn/native/Device.cpp +++ b/src/dawn/native/Device.cpp @@ -171,6 +171,7 @@ ResultOrError> ValidateLayoutAndGetRenderPipelineDescrip DeviceBase::DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor) : mInstance(adapter->GetInstance()), mAdapter(adapter), mNextPipelineCompatibilityToken(1) { + mInstance->IncrementDeviceCountForTesting(); ASSERT(descriptor != nullptr); AdapterProperties adapterProperties; @@ -220,6 +221,10 @@ DeviceBase::~DeviceBase() { // We need to explicitly release the Queue before we complete the destructor so that the // Queue does not get destroyed after the Device. mQueue = nullptr; + // mInstance is not set for mock test devices. + if (mInstance != nullptr) { + mInstance->DecrementDeviceCountForTesting(); + } } MaybeError DeviceBase::Initialize(Ref defaultQueue) { diff --git a/src/dawn/native/Instance.cpp b/src/dawn/native/Instance.cpp index 1e25a3be01..4047865a5d 100644 --- a/src/dawn/native/Instance.cpp +++ b/src/dawn/native/Instance.cpp @@ -437,6 +437,18 @@ BlobCache* InstanceBase::GetBlobCache() { return mBlobCache.get(); } +uint64_t InstanceBase::GetDeviceCountForTesting() const { + return mDeviceCountForTesting.load(); +} + +void InstanceBase::IncrementDeviceCountForTesting() { + mDeviceCountForTesting++; +} + +void InstanceBase::DecrementDeviceCountForTesting() { + mDeviceCountForTesting--; +} + const std::vector& InstanceBase::GetRuntimeSearchPaths() const { return mRuntimeSearchPaths; } diff --git a/src/dawn/native/Instance.h b/src/dawn/native/Instance.h index 0f3cb18470..581cb8519b 100644 --- a/src/dawn/native/Instance.h +++ b/src/dawn/native/Instance.h @@ -84,6 +84,10 @@ class InstanceBase final : public RefCounted { dawn::platform::Platform* GetPlatform(); BlobCache* GetBlobCache(); + uint64_t GetDeviceCountForTesting() const; + void IncrementDeviceCountForTesting(); + void DecrementDeviceCountForTesting(); + const std::vector& GetRuntimeSearchPaths() const; // Get backend-independent libraries that need to be loaded dynamically. @@ -130,6 +134,8 @@ class InstanceBase final : public RefCounted { #if defined(DAWN_USE_X11) std::unique_ptr mXlibXcbFunctions; #endif // defined(DAWN_USE_X11) + + std::atomic_uint64_t mDeviceCountForTesting{0}; }; } // namespace dawn::native diff --git a/src/dawn/tests/BUILD.gn b/src/dawn/tests/BUILD.gn index b1a2b74d85..9f86b590d3 100644 --- a/src/dawn/tests/BUILD.gn +++ b/src/dawn/tests/BUILD.gn @@ -491,12 +491,6 @@ source_set("end2end_tests_sources") { "end2end/ViewportTests.cpp", ] - # Validation tests that need OS windows live in end2end tests. - sources += [ - "unittests/validation/ValidationTest.cpp", - "unittests/validation/ValidationTest.h", - ] - libs = [] if (dawn_enable_d3d12) { diff --git a/src/dawn/tests/DawnNativeTest.cpp b/src/dawn/tests/DawnNativeTest.cpp index c07c5c27d8..163413dc1e 100644 --- a/src/dawn/tests/DawnNativeTest.cpp +++ b/src/dawn/tests/DawnNativeTest.cpp @@ -62,7 +62,7 @@ void DawnNativeTest::SetUp() { ASSERT(foundNullAdapter); - device = wgpu::Device(CreateTestDevice()); + device = wgpu::Device::Acquire(CreateTestDevice()); device.SetUncapturedErrorCallback(DawnNativeTest::OnDeviceError, nullptr); } diff --git a/src/dawn/tests/DawnTest.cpp b/src/dawn/tests/DawnTest.cpp index 148bf0a5aa..a5dffad9f8 100644 --- a/src/dawn/tests/DawnTest.cpp +++ b/src/dawn/tests/DawnTest.cpp @@ -723,6 +723,9 @@ DawnTestBase::~DawnTestBase() { mBackendAdapter.ResetInternalDeviceForTesting(); } mWireHelper.reset(); + + // Check that all devices were destructed. + EXPECT_EQ(gTestEnv->GetInstance()->GetDeviceCountForTesting(), 0u); } bool DawnTestBase::IsD3D12() const { diff --git a/src/dawn/tests/unittests/FeatureTests.cpp b/src/dawn/tests/unittests/FeatureTests.cpp index 9fb6248ced..cb7d7014ce 100644 --- a/src/dawn/tests/unittests/FeatureTests.cpp +++ b/src/dawn/tests/unittests/FeatureTests.cpp @@ -84,5 +84,6 @@ TEST_F(FeatureTests, GetEnabledFeatures) { wgpu::FeatureName enabledFeature; deviceBase->APIEnumerateFeatures(&enabledFeature); EXPECT_EQ(enabledFeature, featureName); + deviceBase->APIRelease(); } } diff --git a/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp b/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp index e3939249ae..9ffba5dc88 100644 --- a/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp @@ -23,8 +23,8 @@ using ::testing::HasSubstr; class RequestDeviceValidationTest : public ValidationTest { protected: void SetUp() override { - DAWN_SKIP_TEST_IF(UsesWire()); ValidationTest::SetUp(); + DAWN_SKIP_TEST_IF(UsesWire()); } static void ExpectRequestDeviceSuccess(WGPURequestDeviceStatus status, diff --git a/src/dawn/tests/unittests/validation/LabelTests.cpp b/src/dawn/tests/unittests/validation/LabelTests.cpp index 5b1b3ea696..ebecbf699b 100644 --- a/src/dawn/tests/unittests/validation/LabelTests.cpp +++ b/src/dawn/tests/unittests/validation/LabelTests.cpp @@ -325,7 +325,7 @@ TEST_F(LabelTest, Queue) { // The label should be empty if one was not set. { wgpu::DeviceDescriptor descriptor; - wgpu::Device labelDevice = adapter.CreateDevice(&descriptor); + wgpu::Device labelDevice = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); std::string readbackLabel = dawn::native::GetObjectLabelForTesting(labelDevice.GetQueue().Get()); ASSERT_TRUE(readbackLabel.empty()); @@ -334,7 +334,7 @@ TEST_F(LabelTest, Queue) { // Test setting a label through API { wgpu::DeviceDescriptor descriptor; - wgpu::Device labelDevice = adapter.CreateDevice(&descriptor); + wgpu::Device labelDevice = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); labelDevice.GetQueue().SetLabel(label.c_str()); std::string readbackLabel = dawn::native::GetObjectLabelForTesting(labelDevice.GetQueue().Get()); @@ -345,7 +345,7 @@ TEST_F(LabelTest, Queue) { { wgpu::DeviceDescriptor descriptor; descriptor.defaultQueue.label = label.c_str(); - wgpu::Device labelDevice = adapter.CreateDevice(&descriptor); + wgpu::Device labelDevice = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); std::string readbackLabel = dawn::native::GetObjectLabelForTesting(labelDevice.GetQueue().Get()); ASSERT_EQ(label, readbackLabel); diff --git a/src/dawn/tests/unittests/validation/ToggleValidationTests.cpp b/src/dawn/tests/unittests/validation/ToggleValidationTests.cpp index 1c0d9bec1d..677f6e2253 100644 --- a/src/dawn/tests/unittests/validation/ToggleValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/ToggleValidationTests.cpp @@ -18,7 +18,12 @@ namespace { -class ToggleValidationTest : public ValidationTest {}; +class ToggleValidationTest : public ValidationTest { + void SetUp() override { + ValidationTest::SetUp(); + DAWN_SKIP_TEST_IF(UsesWire()); + } +}; // Tests querying the detail of a toggle from dawn::native::InstanceBase works correctly. TEST_F(ToggleValidationTest, QueryToggleInfo) { @@ -51,8 +56,8 @@ TEST_F(ToggleValidationTest, OverrideToggleUsage) { togglesDesc.forceEnabledToggles = &kValidToggleName; togglesDesc.forceEnabledTogglesCount = 1; - WGPUDevice deviceWithToggle = adapter.CreateDevice(&descriptor); - std::vector toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle); + wgpu::Device deviceWithToggle = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); + std::vector toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle.Get()); bool validToggleExists = false; for (const char* toggle : toggleNames) { if (strcmp(toggle, kValidToggleName) == 0) { @@ -71,8 +76,8 @@ TEST_F(ToggleValidationTest, OverrideToggleUsage) { togglesDesc.forceEnabledToggles = &kInvalidToggleName; togglesDesc.forceEnabledTogglesCount = 1; - WGPUDevice deviceWithToggle = adapter.CreateDevice(&descriptor); - std::vector toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle); + wgpu::Device deviceWithToggle = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); + std::vector toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle.Get()); bool InvalidToggleExists = false; for (const char* toggle : toggleNames) { if (strcmp(toggle, kInvalidToggleName) == 0) { @@ -91,8 +96,8 @@ TEST_F(ToggleValidationTest, TurnOffVsyncWithToggle) { togglesDesc.forceEnabledToggles = &kValidToggleName; togglesDesc.forceEnabledTogglesCount = 1; - WGPUDevice deviceWithToggle = adapter.CreateDevice(&descriptor); - std::vector toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle); + wgpu::Device deviceWithToggle = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor)); + std::vector toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle.Get()); bool validToggleExists = false; for (const char* toggle : toggleNames) { if (strcmp(toggle, kValidToggleName) == 0) { diff --git a/src/dawn/tests/unittests/validation/ValidationTest.cpp b/src/dawn/tests/unittests/validation/ValidationTest.cpp index 38908b5388..14d5372633 100644 --- a/src/dawn/tests/unittests/validation/ValidationTest.cpp +++ b/src/dawn/tests/unittests/validation/ValidationTest.cpp @@ -118,6 +118,9 @@ ValidationTest::~ValidationTest() { // will call a nullptr device = wgpu::Device(); mWireHelper.reset(); + + // Check that all devices were destructed. + EXPECT_EQ(instance->GetDeviceCountForTesting(), 0u); } void ValidationTest::TearDown() { diff --git a/src/dawn/tests/white_box/VulkanImageWrappingTests_DmaBuf.cpp b/src/dawn/tests/white_box/VulkanImageWrappingTests_DmaBuf.cpp index cccaadc533..bf3735917f 100644 --- a/src/dawn/tests/white_box/VulkanImageWrappingTests_DmaBuf.cpp +++ b/src/dawn/tests/white_box/VulkanImageWrappingTests_DmaBuf.cpp @@ -118,7 +118,8 @@ class VulkanImageWrappingTestBackendDmaBuf : public VulkanImageWrappingTestBacke descriptorDmaBuf.stride = textureDmaBuf->stride; descriptorDmaBuf.drmModifier = textureDmaBuf->drmModifier; - return dawn::native::vulkan::WrapVulkanImage(device.Get(), &descriptorDmaBuf); + return wgpu::Texture::Acquire( + dawn::native::vulkan::WrapVulkanImage(device.Get(), &descriptorDmaBuf)); } bool ExportImage(const wgpu::Texture& texture, diff --git a/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp b/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp index c92181ccfc..e8e8a59333 100644 --- a/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp +++ b/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp @@ -141,7 +141,8 @@ class VulkanImageWrappingTestBackendOpaqueFD : public VulkanImageWrappingTestBac descriptorOpaqueFD.memoryTypeIndex = textureOpaqueFD->memoryTypeIndex; descriptorOpaqueFD.waitFDs = std::move(waitFDs); - return dawn::native::vulkan::WrapVulkanImage(device.Get(), &descriptorOpaqueFD); + return wgpu::Texture::Acquire( + dawn::native::vulkan::WrapVulkanImage(device.Get(), &descriptorOpaqueFD)); } bool ExportImage(const wgpu::Texture& texture,