diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp index c924ece745..ce114a5e5e 100644 --- a/src/dawn_native/Device.cpp +++ b/src/dawn_native/Device.cpp @@ -269,7 +269,7 @@ namespace dawn_native { // TODO(dawn/628) Add types into the array as they are implemented. // clang-format off - static constexpr std::array kObjectTypeDependencyOrder = { + static constexpr std::array kObjectTypeDependencyOrder = { ObjectType::RenderPipeline, ObjectType::ComputePipeline, ObjectType::PipelineLayout, @@ -277,6 +277,9 @@ namespace dawn_native { ObjectType::BindGroup, ObjectType::BindGroupLayout, ObjectType::ShaderModule, + ObjectType::ExternalTexture, + ObjectType::TextureView, + ObjectType::Texture, ObjectType::QuerySet, ObjectType::Sampler, ObjectType::Buffer, diff --git a/src/dawn_native/ExternalTexture.cpp b/src/dawn_native/ExternalTexture.cpp index 148e24de3d..f8556d8bdd 100644 --- a/src/dawn_native/ExternalTexture.cpp +++ b/src/dawn_native/ExternalTexture.cpp @@ -91,6 +91,12 @@ namespace dawn_native { const ExternalTextureDescriptor* descriptor) : ApiObjectBase(device, kLabelNotImplemented), mState(ExternalTextureState::Alive) { textureViews[0] = descriptor->plane0; + TrackInDevice(); + } + + ExternalTextureBase::ExternalTextureBase(DeviceBase* device) + : ApiObjectBase(device, kLabelNotImplemented), mState(ExternalTextureState::Alive) { + TrackInDevice(); } ExternalTextureBase::ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag) @@ -113,8 +119,12 @@ namespace dawn_native { if (GetDevice()->ConsumedError(GetDevice()->ValidateObject(this))) { return; } + DestroyApiObject(); + } + + bool ExternalTextureBase::DestroyApiObject() { mState = ExternalTextureState::Destroyed; - ASSERT(!IsError()); + return ApiObjectBase::DestroyApiObject(); } // static diff --git a/src/dawn_native/ExternalTexture.h b/src/dawn_native/ExternalTexture.h index d16147472c..af8264b6a2 100644 --- a/src/dawn_native/ExternalTexture.h +++ b/src/dawn_native/ExternalTexture.h @@ -42,10 +42,15 @@ namespace dawn_native { static ExternalTextureBase* MakeError(DeviceBase* device); + bool DestroyApiObject() override; ObjectType GetType() const override; void APIDestroy(); + protected: + // Constructor used only for mocking and testing. + ExternalTextureBase(DeviceBase* device); + private: enum class ExternalTextureState { Alive, Destroyed }; ExternalTextureBase(DeviceBase* device, const ExternalTextureDescriptor* descriptor); diff --git a/src/dawn_native/Texture.cpp b/src/dawn_native/Texture.cpp index e770ece383..cdfb9ce75d 100644 --- a/src/dawn_native/Texture.cpp +++ b/src/dawn_native/Texture.cpp @@ -469,14 +469,30 @@ namespace dawn_native { if (internalUsageDesc != nullptr) { mInternalUsage |= internalUsageDesc->internalUsage; } + TrackInDevice(); } static Format kUnusedFormat; + TextureBase::TextureBase(DeviceBase* device, TextureState state) + : ApiObjectBase(device, kLabelNotImplemented), mFormat(kUnusedFormat), mState(state) { + TrackInDevice(); + } + TextureBase::TextureBase(DeviceBase* device, ObjectBase::ErrorTag tag) : ApiObjectBase(device, tag), mFormat(kUnusedFormat) { } + bool TextureBase::DestroyApiObject() { + // We need to run the destroy operations prior to setting the state to destroyed so that + // the state is both consistent, and implementations of the destroy that may check the + // state do not skip operations unintentionally. (Example in Vulkan backend, the destroy + // implementation will not be ran if we are already in the Destroyed state.) + bool wasDestroyed = ApiObjectBase::DestroyApiObject(); + mState = TextureState::Destroyed; + return wasDestroyed; + } + // static TextureBase* TextureBase::MakeError(DeviceBase* device) { return new TextureBase(device, ObjectBase::kError); @@ -670,15 +686,7 @@ namespace dawn_native { return; } ASSERT(!IsError()); - DestroyInternal(); - } - - void TextureBase::DestroyImpl() { - } - - void TextureBase::DestroyInternal() { - DestroyImpl(); - mState = TextureState::Destroyed; + DestroyApiObject(); } MaybeError TextureBase::ValidateDestroy() const { @@ -696,6 +704,14 @@ namespace dawn_native { mRange({ConvertViewAspect(mFormat, descriptor->aspect), {descriptor->baseArrayLayer, descriptor->arrayLayerCount}, {descriptor->baseMipLevel, descriptor->mipLevelCount}}) { + TrackInDevice(); + } + + TextureViewBase::TextureViewBase(TextureBase* texture) + : ApiObjectBase(texture->GetDevice(), kLabelNotImplemented), + mTexture(texture), + mFormat(kUnusedFormat) { + TrackInDevice(); } TextureViewBase::TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag) diff --git a/src/dawn_native/Texture.h b/src/dawn_native/Texture.h index 52f5f391e5..e16be4431a 100644 --- a/src/dawn_native/Texture.h +++ b/src/dawn_native/Texture.h @@ -51,6 +51,7 @@ namespace dawn_native { static TextureBase* MakeError(DeviceBase* device); + bool DestroyApiObject() override; ObjectType GetType() const override; wgpu::TextureDimension GetDimension() const; @@ -96,11 +97,11 @@ namespace dawn_native { void APIDestroy(); protected: - void DestroyInternal(); + // Constructor used only for mocking and testing. + TextureBase(DeviceBase* device, TextureState state); private: TextureBase(DeviceBase* device, ObjectBase::ErrorTag tag); - virtual void DestroyImpl(); MaybeError ValidateDestroy() const; wgpu::TextureDimension mDimension; @@ -136,6 +137,10 @@ namespace dawn_native { uint32_t GetLayerCount() const; const SubresourceRange& GetSubresourceRange() const; + protected: + // Constructor used only for mocking and testing. + TextureViewBase(TextureBase* texture); + private: TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag); diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp index c4abeb6512..95d4476990 100644 --- a/src/dawn_native/d3d12/TextureD3D12.cpp +++ b/src/dawn_native/d3d12/TextureD3D12.cpp @@ -647,10 +647,9 @@ namespace dawn_native { namespace d3d12 { } Texture::~Texture() { - DestroyInternal(); } - void Texture::DestroyImpl() { + void Texture::DestroyApiObjectImpl() { Device* device = ToBackend(GetDevice()); // In PIX's D3D12-only mode, there is no way to determine frame boundaries diff --git a/src/dawn_native/d3d12/TextureD3D12.h b/src/dawn_native/d3d12/TextureD3D12.h index 4d49d6fa9f..6919e202fb 100644 --- a/src/dawn_native/d3d12/TextureD3D12.h +++ b/src/dawn_native/d3d12/TextureD3D12.h @@ -105,7 +105,7 @@ namespace dawn_native { namespace d3d12 { // Dawn API void SetLabelImpl() override; - void DestroyImpl() override; + void DestroyApiObjectImpl() override; MaybeError ClearTexture(CommandRecordingContext* commandContext, const SubresourceRange& range, diff --git a/src/dawn_native/metal/TextureMTL.h b/src/dawn_native/metal/TextureMTL.h index bfcf02f8fb..be32b8e2e0 100644 --- a/src/dawn_native/metal/TextureMTL.h +++ b/src/dawn_native/metal/TextureMTL.h @@ -66,7 +66,7 @@ namespace dawn_native { namespace metal { void InitializeAsWrapping(const TextureDescriptor* descriptor, NSPRef> wrapped); - void DestroyImpl() override; + void DestroyApiObjectImpl() override; MaybeError ClearTexture(CommandRecordingContext* commandContext, const SubresourceRange& range, diff --git a/src/dawn_native/metal/TextureMTL.mm b/src/dawn_native/metal/TextureMTL.mm index a611e3fd1c..34d2694ec4 100644 --- a/src/dawn_native/metal/TextureMTL.mm +++ b/src/dawn_native/metal/TextureMTL.mm @@ -493,10 +493,9 @@ namespace dawn_native { namespace metal { } Texture::~Texture() { - DestroyInternal(); } - void Texture::DestroyImpl() { + void Texture::DestroyApiObjectImpl() { mMtlTexture = nullptr; } diff --git a/src/dawn_native/opengl/TextureGL.cpp b/src/dawn_native/opengl/TextureGL.cpp index f8f76bf65d..8fc3f0e8b8 100644 --- a/src/dawn_native/opengl/TextureGL.cpp +++ b/src/dawn_native/opengl/TextureGL.cpp @@ -188,10 +188,9 @@ namespace dawn_native { namespace opengl { } Texture::~Texture() { - DestroyInternal(); } - void Texture::DestroyImpl() { + void Texture::DestroyApiObjectImpl() { if (GetTextureState() == TextureState::OwnedInternal) { ToBackend(GetDevice())->gl.DeleteTextures(1, &mHandle); mHandle = 0; @@ -559,6 +558,9 @@ namespace dawn_native { namespace opengl { } TextureView::~TextureView() { + } + + void TextureView::DestroyApiObjectImpl() { if (mOwnsHandle) { ToBackend(GetDevice())->gl.DeleteTextures(1, &mHandle); } diff --git a/src/dawn_native/opengl/TextureGL.h b/src/dawn_native/opengl/TextureGL.h index a01b94348b..6f92134ad0 100644 --- a/src/dawn_native/opengl/TextureGL.h +++ b/src/dawn_native/opengl/TextureGL.h @@ -41,7 +41,7 @@ namespace dawn_native { namespace opengl { private: ~Texture() override; - void DestroyImpl() override; + void DestroyApiObjectImpl() override; MaybeError ClearTexture(const SubresourceRange& range, TextureBase::ClearValue clearValue); GLuint mHandle; @@ -57,6 +57,7 @@ namespace dawn_native { namespace opengl { private: ~TextureView() override; + void DestroyApiObjectImpl() override; GLuint mHandle; GLenum mTarget; diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp index 5f37b3e476..9b220f5286 100644 --- a/src/dawn_native/vulkan/TextureVk.cpp +++ b/src/dawn_native/vulkan/TextureVk.cpp @@ -792,12 +792,11 @@ namespace dawn_native { namespace vulkan { mSignalSemaphore = VK_NULL_HANDLE; // Destroy the texture so it can't be used again - DestroyInternal(); + DestroyApiObject(); return {}; } Texture::~Texture() { - DestroyInternal(); } void Texture::SetLabelHelper(const char* prefix) { @@ -809,7 +808,7 @@ namespace dawn_native { namespace vulkan { SetLabelHelper("Dawn_InternalTexture"); } - void Texture::DestroyImpl() { + void Texture::DestroyApiObjectImpl() { if (GetTextureState() == TextureState::OwnedInternal) { Device* device = ToBackend(GetDevice()); @@ -1300,6 +1299,9 @@ namespace dawn_native { namespace vulkan { } TextureView::~TextureView() { + } + + void TextureView::DestroyApiObjectImpl() { Device* device = ToBackend(GetTexture()->GetDevice()); if (mHandle != VK_NULL_HANDLE) { diff --git a/src/dawn_native/vulkan/TextureVk.h b/src/dawn_native/vulkan/TextureVk.h index 779d51b339..d2f5676838 100644 --- a/src/dawn_native/vulkan/TextureVk.h +++ b/src/dawn_native/vulkan/TextureVk.h @@ -107,7 +107,7 @@ namespace dawn_native { namespace vulkan { external_memory::Service* externalMemoryService); void InitializeForSwapChain(VkImage nativeImage); - void DestroyImpl() override; + void DestroyApiObjectImpl() override; MaybeError ClearTexture(CommandRecordingContext* recordingContext, const SubresourceRange& range, TextureBase::ClearValue); @@ -176,6 +176,7 @@ namespace dawn_native { namespace vulkan { private: ~TextureView() override; + void DestroyApiObjectImpl() override; using TextureViewBase::TextureViewBase; MaybeError Initialize(const TextureViewDescriptor* descriptor); diff --git a/src/tests/BUILD.gn b/src/tests/BUILD.gn index 8ac2c9f542..d903f8ffe2 100644 --- a/src/tests/BUILD.gn +++ b/src/tests/BUILD.gn @@ -146,6 +146,7 @@ source_set("dawn_native_mocks_sources") { "unittests/native/mocks/BindGroupMock.h", "unittests/native/mocks/ComputePipelineMock.h", "unittests/native/mocks/DeviceMock.h", + "unittests/native/mocks/ExternalTextureMock.h", "unittests/native/mocks/PipelineLayoutMock.h", "unittests/native/mocks/QuerySetMock.h", "unittests/native/mocks/RenderPipelineMock.h", @@ -153,6 +154,7 @@ source_set("dawn_native_mocks_sources") { "unittests/native/mocks/ShaderModuleMock.cpp", "unittests/native/mocks/ShaderModuleMock.h", "unittests/native/mocks/SwapChainMock.h", + "unittests/native/mocks/TextureMock.h", ] } diff --git a/src/tests/unittests/native/DestroyObjectTests.cpp b/src/tests/unittests/native/DestroyObjectTests.cpp index e4dee5edb1..7623a26b3e 100644 --- a/src/tests/unittests/native/DestroyObjectTests.cpp +++ b/src/tests/unittests/native/DestroyObjectTests.cpp @@ -20,12 +20,14 @@ #include "mocks/BufferMock.h" #include "mocks/ComputePipelineMock.h" #include "mocks/DeviceMock.h" +#include "mocks/ExternalTextureMock.h" #include "mocks/PipelineLayoutMock.h" #include "mocks/QuerySetMock.h" #include "mocks/RenderPipelineMock.h" #include "mocks/SamplerMock.h" #include "mocks/ShaderModuleMock.h" #include "mocks/SwapChainMock.h" +#include "mocks/TextureMock.h" #include "tests/DawnNativeTest.h" #include "utils/ComboRenderPipelineDescriptor.h" @@ -44,6 +46,16 @@ namespace dawn_native { namespace { mDevice.SetToggle(Toggle::SkipValidation, true); } + Ref GetTexture() { + if (mTexture != nullptr) { + return mTexture; + } + mTexture = + AcquireRef(new TextureMock(&mDevice, TextureBase::TextureState::OwnedInternal)); + EXPECT_CALL(*mTexture.Get(), DestroyApiObjectImpl).Times(1); + return mTexture; + } + Ref GetPipelineLayout() { if (mPipelineLayout != nullptr) { return mPipelineLayout; @@ -85,6 +97,7 @@ namespace dawn_native { namespace { // The following lazy-initialized objects are used to facilitate creation of dependent // objects under test. + Ref mTexture; Ref mPipelineLayout; Ref mVsModule; Ref mCsModule; @@ -237,6 +250,24 @@ namespace dawn_native { namespace { } } + TEST_F(DestroyObjectTests, ExternalTextureExplicit) { + ExternalTextureMock externalTextureMock(&mDevice); + EXPECT_CALL(externalTextureMock, DestroyApiObjectImpl).Times(1); + + EXPECT_TRUE(externalTextureMock.IsAlive()); + externalTextureMock.DestroyApiObject(); + EXPECT_FALSE(externalTextureMock.IsAlive()); + } + + // We can use an actual ExternalTexture object to test the implicit case. + TEST_F(DestroyObjectTests, ExternalTextureImplicit) { + ExternalTextureDescriptor desc = {}; + Ref externalTexture; + DAWN_ASSERT_AND_ASSIGN(externalTexture, mDevice.CreateExternalTexture(&desc)); + + EXPECT_TRUE(externalTexture->IsAlive()); + } + TEST_F(DestroyObjectTests, PipelineLayoutExplicit) { PipelineLayoutMock pipelineLayoutMock(&mDevice); EXPECT_CALL(pipelineLayoutMock, DestroyApiObjectImpl).Times(1); @@ -409,6 +440,84 @@ namespace dawn_native { namespace { } } + TEST_F(DestroyObjectTests, TextureExplicit) { + { + TextureMock textureMock(&mDevice, TextureBase::TextureState::OwnedInternal); + EXPECT_CALL(textureMock, DestroyApiObjectImpl).Times(1); + + EXPECT_TRUE(textureMock.IsAlive()); + textureMock.DestroyApiObject(); + EXPECT_FALSE(textureMock.IsAlive()); + } + { + TextureMock textureMock(&mDevice, TextureBase::TextureState::OwnedExternal); + EXPECT_CALL(textureMock, DestroyApiObjectImpl).Times(1); + + EXPECT_TRUE(textureMock.IsAlive()); + textureMock.DestroyApiObject(); + EXPECT_FALSE(textureMock.IsAlive()); + } + } + + // If the reference count on API objects reach 0, they should delete themselves. Note that GTest + // will also complain if there is a memory leak. + TEST_F(DestroyObjectTests, TextureImplicit) { + { + TextureMock* textureMock = + new TextureMock(&mDevice, TextureBase::TextureState::OwnedInternal); + EXPECT_CALL(*textureMock, DestroyApiObjectImpl).Times(1); + { + TextureDescriptor desc = {}; + Ref texture; + EXPECT_CALL(mDevice, CreateTextureImpl) + .WillOnce(Return(ByMove(AcquireRef(textureMock)))); + DAWN_ASSERT_AND_ASSIGN(texture, mDevice.CreateTexture(&desc)); + + EXPECT_TRUE(texture->IsAlive()); + } + } + { + TextureMock* textureMock = + new TextureMock(&mDevice, TextureBase::TextureState::OwnedExternal); + EXPECT_CALL(*textureMock, DestroyApiObjectImpl).Times(1); + { + TextureDescriptor desc = {}; + Ref texture; + EXPECT_CALL(mDevice, CreateTextureImpl) + .WillOnce(Return(ByMove(AcquireRef(textureMock)))); + DAWN_ASSERT_AND_ASSIGN(texture, mDevice.CreateTexture(&desc)); + + EXPECT_TRUE(texture->IsAlive()); + } + } + } + + TEST_F(DestroyObjectTests, TextureViewExplicit) { + TextureViewMock textureViewMock(GetTexture().Get()); + EXPECT_CALL(textureViewMock, DestroyApiObjectImpl).Times(1); + + EXPECT_TRUE(textureViewMock.IsAlive()); + textureViewMock.DestroyApiObject(); + EXPECT_FALSE(textureViewMock.IsAlive()); + } + + // If the reference count on API objects reach 0, they should delete themselves. Note that GTest + // will also complain if there is a memory leak. + TEST_F(DestroyObjectTests, TextureViewImplicit) { + TextureViewMock* textureViewMock = new TextureViewMock(GetTexture().Get()); + EXPECT_CALL(*textureViewMock, DestroyApiObjectImpl).Times(1); + { + TextureViewDescriptor desc = {}; + Ref textureView; + EXPECT_CALL(mDevice, CreateTextureViewImpl) + .WillOnce(Return(ByMove(AcquireRef(textureViewMock)))); + DAWN_ASSERT_AND_ASSIGN(textureView, + mDevice.CreateTextureView(GetTexture().Get(), &desc)); + + EXPECT_TRUE(textureView->IsAlive()); + } + } + // Destroying the objects on the mDevice should result in all created objects being destroyed in // order. TEST_F(DestroyObjectTests, DestroyObjects) { @@ -422,6 +531,9 @@ namespace dawn_native { namespace { SamplerMock* samplerMock = new SamplerMock(&mDevice); ShaderModuleMock* shaderModuleMock = new ShaderModuleMock(&mDevice); SwapChainMock* swapChainMock = new SwapChainMock(&mDevice); + TextureMock* textureMock = + new TextureMock(&mDevice, TextureBase::TextureState::OwnedInternal); + TextureViewMock* textureViewMock = new TextureViewMock(GetTexture().Get()); { InSequence seq; EXPECT_CALL(*renderPipelineMock, DestroyApiObjectImpl).Times(1); @@ -431,6 +543,8 @@ namespace dawn_native { namespace { EXPECT_CALL(*bindGroupMock, DestroyApiObjectImpl).Times(1); EXPECT_CALL(*bindGroupLayoutMock, DestroyApiObjectImpl).Times(1); EXPECT_CALL(*shaderModuleMock, DestroyApiObjectImpl).Times(1); + EXPECT_CALL(*textureViewMock, DestroyApiObjectImpl).Times(1); + EXPECT_CALL(*textureMock, DestroyApiObjectImpl).Times(1); EXPECT_CALL(*querySetMock, DestroyApiObjectImpl).Times(1); EXPECT_CALL(*samplerMock, DestroyApiObjectImpl).Times(1); EXPECT_CALL(*bufferMock, DestroyApiObjectImpl).Times(1); @@ -484,6 +598,13 @@ namespace dawn_native { namespace { EXPECT_TRUE(computePipeline->IsCachedReference()); } + Ref externalTexture; + { + ExternalTextureDescriptor desc = {}; + DAWN_ASSERT_AND_ASSIGN(externalTexture, mDevice.CreateExternalTexture(&desc)); + EXPECT_TRUE(externalTexture->IsAlive()); + } + Ref pipelineLayout; { PipelineLayoutDescriptor desc = {}; @@ -560,17 +681,39 @@ namespace dawn_native { namespace { EXPECT_TRUE(swapChain->IsAlive()); } + Ref texture; + { + TextureDescriptor desc = {}; + EXPECT_CALL(mDevice, CreateTextureImpl) + .WillOnce(Return(ByMove(AcquireRef(textureMock)))); + DAWN_ASSERT_AND_ASSIGN(texture, mDevice.CreateTexture(&desc)); + EXPECT_TRUE(texture->IsAlive()); + } + + Ref textureView; + { + TextureViewDescriptor desc = {}; + EXPECT_CALL(mDevice, CreateTextureViewImpl) + .WillOnce(Return(ByMove(AcquireRef(textureViewMock)))); + DAWN_ASSERT_AND_ASSIGN(textureView, + mDevice.CreateTextureView(GetTexture().Get(), &desc)); + EXPECT_TRUE(textureView->IsAlive()); + } + mDevice.DestroyObjects(); EXPECT_FALSE(bindGroup->IsAlive()); EXPECT_FALSE(bindGroupLayout->IsAlive()); EXPECT_FALSE(buffer->IsAlive()); EXPECT_FALSE(computePipeline->IsAlive()); + EXPECT_FALSE(externalTexture->IsAlive()); EXPECT_FALSE(pipelineLayout->IsAlive()); EXPECT_FALSE(querySet->IsAlive()); EXPECT_FALSE(renderPipeline->IsAlive()); EXPECT_FALSE(sampler->IsAlive()); EXPECT_FALSE(shaderModule->IsAlive()); EXPECT_FALSE(swapChain->IsAlive()); + EXPECT_FALSE(texture->IsAlive()); + EXPECT_FALSE(textureView->IsAlive()); } }} // namespace dawn_native:: diff --git a/src/tests/unittests/native/mocks/ExternalTextureMock.h b/src/tests/unittests/native/mocks/ExternalTextureMock.h new file mode 100644 index 0000000000..617de3fff8 --- /dev/null +++ b/src/tests/unittests/native/mocks/ExternalTextureMock.h @@ -0,0 +1,36 @@ +// Copyright 2021 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef TESTS_UNITTESTS_NATIVE_MOCKS_EXTERNALTEXTURE_MOCK_H_ +#define TESTS_UNITTESTS_NATIVE_MOCKS_EXTERNALTEXTURE_MOCK_H_ + +#include "dawn_native/Device.h" +#include "dawn_native/ExternalTexture.h" + +#include + +namespace dawn_native { + + class ExternalTextureMock : public ExternalTextureBase { + public: + ExternalTextureMock(DeviceBase* device) : ExternalTextureBase(device) { + } + ~ExternalTextureMock() override = default; + + MOCK_METHOD(void, DestroyApiObjectImpl, (), (override)); + }; + +} // namespace dawn_native + +#endif // TESTS_UNITTESTS_NATIVE_MOCKS_EXTERNALTEXTURE_MOCK_H_ diff --git a/src/tests/unittests/native/mocks/TextureMock.h b/src/tests/unittests/native/mocks/TextureMock.h new file mode 100644 index 0000000000..2108cfe4df --- /dev/null +++ b/src/tests/unittests/native/mocks/TextureMock.h @@ -0,0 +1,46 @@ +// Copyright 2021 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef TESTS_UNITTESTS_NATIVE_MOCKS_TEXTURE_MOCK_H_ +#define TESTS_UNITTESTS_NATIVE_MOCKS_TEXTURE_MOCK_H_ + +#include "dawn_native/Device.h" +#include "dawn_native/Texture.h" + +#include + +namespace dawn_native { + + class TextureMock : public TextureBase { + public: + TextureMock(DeviceBase* device, TextureBase::TextureState state) + : TextureBase(device, state) { + } + ~TextureMock() override = default; + + MOCK_METHOD(void, DestroyApiObjectImpl, (), (override)); + }; + + class TextureViewMock : public TextureViewBase { + public: + TextureViewMock(TextureBase* texture) : TextureViewBase(texture) { + } + ~TextureViewMock() override = default; + + MOCK_METHOD(void, DestroyApiObjectImpl, (), (override)); + }; + +} // namespace dawn_native + +#endif // TESTS_UNITTESTS_NATIVE_MOCKS_TEXTURE_MOCK_H_