// Copyright 2021 The Dawn & Tint Authors // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // 3. Neither the name of the copyright holder nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <gtest/gtest.h> #include <webgpu/webgpu_cpp.h> #include <utility> #include <vector> #include "dawn/native/ChainUtils.h" #include "dawn/native/Toggles.h" #include "dawn/native/utils/WGPUHelpers.h" #include "dawn/tests/DawnNativeTest.h" #include "dawn/tests/MockCallback.h" #include "dawn/utils/ComboRenderPipelineDescriptor.h" #include "dawn/utils/WGPUHelpers.h" #include "mocks/BindGroupLayoutMock.h" #include "mocks/BindGroupMock.h" #include "mocks/BufferMock.h" #include "mocks/CommandBufferMock.h" #include "mocks/ComputePipelineMock.h" #include "mocks/DawnMockTest.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 "partition_alloc/pointers/raw_ptr.h" namespace dawn::native { namespace { _; ByMove; InSequence; Mock; MockCppCallback; NiceMock; Return; StrictMock; Test; MockMapAsyncCallback; static constexpr std::string_view kComputeShader = …; static constexpr std::string_view kVertexShader = …; static constexpr std::string_view kFragmentShader = …; // Stores and scopes a raw mock object ptr expectation. This is particularly useful on objects that // are expected to be destroyed at the end of the scope. In most cases, when the validation in this // class's destructor is ran, the pointer is probably already freed. class ScopedRawPtrExpectation { … }; class DestroyObjectTests : public DawnMockTest { … }; TEST_F(DestroyObjectTests, BindGroupNativeExplicit) { … } // 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, BindGroupImplicit) { … } TEST_F(DestroyObjectTests, BindGroupLayoutNativeExplicit) { … } // 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, BindGroupLayoutImplicit) { … } TEST_F(DestroyObjectTests, BufferNativeExplicit) { … } TEST_F(DestroyObjectTests, BufferApiExplicit) { … } // 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, BufferImplicit) { … } TEST_F(DestroyObjectTests, MappedBufferApiExplicit) { … } // 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, MappedBufferImplicit) { … } TEST_F(DestroyObjectTests, CommandBufferNativeExplicit) { … } // 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, CommandBufferImplicit) { … } TEST_F(DestroyObjectTests, ComputePipelineNativeExplicit) { … } // 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, ComputePipelineImplicit) { … } TEST_F(DestroyObjectTests, ExternalTextureNativeExplicit) { … } TEST_F(DestroyObjectTests, ExternalTextureApiExplicit) { … } TEST_F(DestroyObjectTests, ExternalTextureImplicit) { … } TEST_F(DestroyObjectTests, PipelineLayoutNativeExplicit) { … } // 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, PipelineLayoutImplicit) { … } TEST_F(DestroyObjectTests, QuerySetNativeExplicit) { … } TEST_F(DestroyObjectTests, QuerySetApiExplicit) { … } // 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, QuerySetImplicit) { … } TEST_F(DestroyObjectTests, RenderPipelineNativeExplicit) { … } // 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, RenderPipelineImplicit) { … } TEST_F(DestroyObjectTests, SamplerNativeExplicit) { … } // 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, SamplerImplicit) { … } TEST_F(DestroyObjectTests, ShaderModuleNativeExplicit) { … } TEST_F(DestroyObjectTests, ShaderModuleImplicit) { … } TEST_F(DestroyObjectTests, TextureNativeExplicit) { … } TEST_F(DestroyObjectTests, TextureApiExplicit) { … } // 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) { … } TEST_F(DestroyObjectTests, TextureViewNativeExplicit) { … } TEST_F(DestroyObjectTests, TextureViewApiExplicit) { … } // 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) { … } // Destroying the objects on the device explicitly should result in all created objects being // destroyed in order. TEST_F(DestroyObjectTests, DestroyObjectsApiExplicit) { … } class DestroyObjectRegressionTests : public DawnNativeTest { … }; // LastRefInCommand* tests are regression test(s) for https://crbug.com/chromium/1318792. The // regression tests here are not exhuastive. In order to have an exhuastive test case for this // class of failures, we should test every possible command with the commands holding the last // references (or as last as possible) of their needed objects. For now, including simple cases // including a stripped-down case from the original bug. // Tests that when a RenderPipeline's last reference is held in a command in an unfinished // CommandEncoder, that destroying the device still works as expected (and does not cause // double-free). TEST_F(DestroyObjectRegressionTests, LastRefInCommandRenderPipeline) { … } // Tests that when a ComputePipelines's last reference is held in a command in an unfinished // CommandEncoder, that destroying the device still works as expected (and does not cause // double-free). TEST_F(DestroyObjectRegressionTests, LastRefInCommandComputePipeline) { … } // Tests that when a BindGroup's last reference is held in a command in an unfinished // CommandEncoder, that destroying the device still works as expected (and does not cause // double-free). TEST_F(DestroyObjectRegressionTests, LastRefInCommandBindGroup) { … } } // anonymous namespace } // namespace dawn::native