Adds destroy handling for BindGroupLayout without new backend changes yet.

- Start tracking BindGroupLayout objects at construction
- Utilizes untrack tag for blueprint layouts for caching purposes
- Adds dawn native test file for testing utilities that require static dawn native lib
- Adds testing macros and mocks for simple sanity unit testing

Bug: dawn:628
Change-Id: Ic85b60e9574e67cc5fc1804cc5300cd1f3a0f6fd
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/65862
Commit-Queue: Loko Kung <lokokung@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Loko Kung 2021-10-12 18:53:57 +00:00 committed by Dawn LUCI CQ
parent fc5a7d414f
commit 2f3fe95ad5
22 changed files with 508 additions and 15 deletions

View File

@ -360,7 +360,8 @@ namespace dawn_native {
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device,
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken)
PipelineCompatibilityToken pipelineCompatibilityToken,
ApiObjectBase::UntrackedByDeviceTag tag)
: ApiObjectBase(device, kLabelNotImplemented),
mBindingInfo(BindingIndex(descriptor->entryCount)),
mPipelineCompatibilityToken(pipelineCompatibilityToken) {
@ -387,15 +388,31 @@ namespace dawn_native {
ASSERT(mBindingInfo.size() <= kMaxBindingsPerPipelineLayoutTyped);
}
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device,
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken)
: BindGroupLayoutBase(device, descriptor, pipelineCompatibilityToken, kUntrackedByDevice) {
TrackInDevice();
}
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: ApiObjectBase(device, tag) {
}
BindGroupLayoutBase::~BindGroupLayoutBase() {
// Do not uncache the actual cached object if we are a blueprint
if (IsCachedReference()) {
GetDevice()->UncacheBindGroupLayout(this);
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device)
: ApiObjectBase(device, kLabelNotImplemented) {
TrackInDevice();
}
bool BindGroupLayoutBase::DestroyApiObject() {
bool wasDestroyed = ApiObjectBase::DestroyApiObject();
if (wasDestroyed) {
// Do not uncache the actual cached object if we are a blueprint
if (IsCachedReference()) {
GetDevice()->UncacheBindGroupLayout(this);
}
}
return wasDestroyed;
}
// static

View File

@ -42,13 +42,17 @@ namespace dawn_native {
// into a packed range of |BindingIndex| integers.
class BindGroupLayoutBase : public ApiObjectBase, public CachedObject {
public:
BindGroupLayoutBase(DeviceBase* device,
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken,
ApiObjectBase::UntrackedByDeviceTag tag);
BindGroupLayoutBase(DeviceBase* device,
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken);
~BindGroupLayoutBase() override;
static BindGroupLayoutBase* MakeError(DeviceBase* device);
bool DestroyApiObject() override;
ObjectType GetType() const override;
// A map from the BindingNumber to its packed BindingIndex.
@ -85,7 +89,6 @@ namespace dawn_native {
// ignoring their compatibility groups.
bool IsLayoutEqual(const BindGroupLayoutBase* other,
bool excludePipelineCompatibiltyToken = false) const;
PipelineCompatibilityToken GetPipelineCompatibilityToken() const;
struct BufferBindingData {
@ -110,6 +113,9 @@ namespace dawn_native {
BindingDataPointers ComputeBindingDataPointers(void* dataStart) const;
protected:
// Constructor used only for mocking and testing.
BindGroupLayoutBase(DeviceBase* device);
template <typename BindGroup>
SlabAllocator<BindGroup> MakeFrontendBindGroupAllocator(size_t size) {
return SlabAllocator<BindGroup>(

View File

@ -200,6 +200,10 @@ namespace dawn_native {
}
}
DeviceBase::DeviceBase() : mState(State::Alive) {
mCaches = std::make_unique<DeviceBase::Caches>();
}
DeviceBase::~DeviceBase() = default;
MaybeError DeviceBase::Initialize(QueueBase* defaultQueue) {
@ -270,7 +274,9 @@ namespace dawn_native {
// that this only considers the immediate frontend dependencies, while backend objects could
// add complications and extra dependencies.
// TODO(dawn/628) Add types into the array as they are implemented.
static constexpr std::array<ObjectType, 0> kObjectTypeDependencyOrder = {};
static constexpr std::array<ObjectType, 1> kObjectTypeDependencyOrder = {
ObjectType::BindGroupLayout,
};
// We first move all objects out from the tracking list into a separate list so that we can
// avoid locking the same mutex twice. We can then iterate across the separate list to call
@ -631,7 +637,8 @@ namespace dawn_native {
ResultOrError<Ref<BindGroupLayoutBase>> DeviceBase::GetOrCreateBindGroupLayout(
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) {
BindGroupLayoutBase blueprint(this, descriptor, pipelineCompatibilityToken);
BindGroupLayoutBase blueprint(this, descriptor, pipelineCompatibilityToken,
ApiObjectBase::kUntrackedByDevice);
const size_t blueprintHash = blueprint.ComputeContentHash();
blueprint.SetContentHash(blueprintHash);

View File

@ -23,6 +23,7 @@
#include "dawn_native/Limits.h"
#include "dawn_native/ObjectBase.h"
#include "dawn_native/ObjectType_autogen.h"
#include "dawn_native/RenderPipeline.h"
#include "dawn_native/StagingBuffer.h"
#include "dawn_native/Toggles.h"
@ -354,6 +355,9 @@ namespace dawn_native {
void APISetLabel(const char* label);
protected:
// Constructor used only for mocking and testing.
DeviceBase();
void SetToggle(Toggle toggle, bool isEnabled);
void ForceSetToggle(Toggle toggle, bool isEnabled);

View File

@ -135,13 +135,52 @@ namespace dawn_native {
// DAWN_TRY_ASSIGN is the same as DAWN_TRY for ResultOrError and assigns the success value, if
// any, to VAR.
#define DAWN_TRY_ASSIGN(VAR, EXPR) \
#define DAWN_TRY_ASSIGN(VAR, EXPR) DAWN_TRY_ASSIGN_WITH_CLEANUP(VAR, EXPR, {})
// Argument helpers are used to determine which macro implementations should be called when
// overloading with different number of variables.
#define DAWN_ERROR_UNIMPLEMENTED_MACRO_(...) UNREACHABLE()
#define DAWN_ERROR_GET_5TH_ARG_HELPER_(_1, _2, _3, _4, NAME, ...) NAME
#define DAWN_ERROR_GET_5TH_ARG_(args) DAWN_ERROR_GET_5TH_ARG_HELPER_ args
// DAWN_TRY_ASSIGN_WITH_CLEANUP is overloaded with 2 version so that users can override the
// return value of the macro when necessary. This is particularly useful if the function
// calling the macro may want to return void instead of the error, i.e. in a test where we may
// just want to assert and fail if the assign cannot go through. In both the cleanup and return
// clauses, users can use the `error` variable to access the pointer to the acquired error.
//
// Example usages:
// 3 Argument Case:
// Result res;
// DAWN_TRY_ASSIGN_WITH_CLEANUP(
// res, GetResultOrErrorFunction(), { AddAdditionalErrorInformation(error.get()); }
// );
//
// 4 Argument Case:
// bool FunctionThatReturnsBool() {
// DAWN_TRY_ASSIGN_WITH_CLEANUP(
// res, GetResultOrErrorFunction(),
// { AddAdditionalErrorInformation(error.get()); },
// false
// );
// }
#define DAWN_TRY_ASSIGN_WITH_CLEANUP(...) \
DAWN_ERROR_GET_5TH_ARG_((__VA_ARGS__, DAWN_TRY_ASSIGN_WITH_CLEANUP_IMPL_4_, \
DAWN_TRY_ASSIGN_WITH_CLEANUP_IMPL_3_, \
DAWN_ERROR_UNIMPLEMENTED_MACRO_)) \
(__VA_ARGS__)
#define DAWN_TRY_ASSIGN_WITH_CLEANUP_IMPL_3_(VAR, EXPR, BODY) \
DAWN_TRY_ASSIGN_WITH_CLEANUP_IMPL_4_(VAR, EXPR, BODY, std::move(error))
#define DAWN_TRY_ASSIGN_WITH_CLEANUP_IMPL_4_(VAR, EXPR, BODY, RET) \
{ \
auto DAWN_LOCAL_VAR = EXPR; \
if (DAWN_UNLIKELY(DAWN_LOCAL_VAR.IsError())) { \
std::unique_ptr<ErrorData> error = DAWN_LOCAL_VAR.AcquireError(); \
{BODY} /* comment to force the formatter to insert a newline */ \
error->AppendBacktrace(__FILE__, __func__, __LINE__); \
return {std::move(error)}; \
return (RET); \
} \
VAR = DAWN_LOCAL_VAR.AcquireSuccess(); \
} \

View File

@ -45,6 +45,8 @@ namespace dawn_native {
public:
struct LabelNotImplementedTag {};
static constexpr LabelNotImplementedTag kLabelNotImplemented = {};
struct UntrackedByDeviceTag {};
static constexpr UntrackedByDeviceTag kUntrackedByDevice = {};
ApiObjectBase(DeviceBase* device, LabelNotImplementedTag tag);
ApiObjectBase(DeviceBase* device, const char* label);

View File

@ -131,6 +131,10 @@ namespace dawn_native { namespace d3d12 {
device->GetSamplerStagingDescriptorAllocator(GetSamplerDescriptorCount());
}
BindGroupLayout::~BindGroupLayout() {
DestroyApiObject();
}
ResultOrError<Ref<BindGroup>> BindGroupLayout::AllocateBindGroup(
Device* device,
const BindGroupDescriptor* descriptor) {

View File

@ -64,7 +64,7 @@ namespace dawn_native { namespace d3d12 {
BindGroupLayout(Device* device,
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken);
~BindGroupLayout() override = default;
~BindGroupLayout() override;
// Contains the offset into the descriptor heap for the given resource view. Samplers and
// non-samplers are stored in separate descriptor heaps, so the offsets should be unique

View File

@ -36,7 +36,7 @@ namespace dawn_native { namespace metal {
BindGroupLayout(DeviceBase* device,
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken);
~BindGroupLayout() override = default;
~BindGroupLayout() override;
SlabAllocator<BindGroup> mBindGroupAllocator;
};

View File

@ -33,6 +33,10 @@ namespace dawn_native { namespace metal {
mBindGroupAllocator(MakeFrontendBindGroupAllocator<BindGroup>(4096)) {
}
BindGroupLayout::~BindGroupLayout() {
DestroyApiObject();
}
Ref<BindGroup> BindGroupLayout::AllocateBindGroup(Device* device,
const BindGroupDescriptor* descriptor) {
return AcquireRef(mBindGroupAllocator.Allocate(device, descriptor));

View File

@ -263,6 +263,18 @@ namespace dawn_native { namespace null {
BindGroupBase(device, descriptor, mBindingDataAllocation) {
}
// BindGroupLayout
BindGroupLayout::BindGroupLayout(DeviceBase* device,
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken)
: BindGroupLayoutBase(device, descriptor, pipelineCompatibilityToken) {
}
BindGroupLayout::~BindGroupLayout() {
DestroyApiObject();
}
// Buffer
Buffer::Buffer(Device* device, const BufferDescriptor* descriptor)

View File

@ -40,7 +40,7 @@ namespace dawn_native { namespace null {
class Adapter;
class BindGroup;
using BindGroupLayout = BindGroupLayoutBase;
class BindGroupLayout;
class Buffer;
class CommandBuffer;
using ComputePipeline = ComputePipelineBase;
@ -200,6 +200,16 @@ namespace dawn_native { namespace null {
~BindGroup() override = default;
};
class BindGroupLayout final : public BindGroupLayoutBase {
public:
BindGroupLayout(DeviceBase* device,
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken);
private:
~BindGroupLayout() override;
};
class Buffer final : public BufferBase {
public:
Buffer(Device* device, const BufferDescriptor* descriptor);

View File

@ -25,6 +25,10 @@ namespace dawn_native { namespace opengl {
mBindGroupAllocator(MakeFrontendBindGroupAllocator<BindGroup>(4096)) {
}
BindGroupLayout::~BindGroupLayout() {
DestroyApiObject();
}
Ref<BindGroup> BindGroupLayout::AllocateBindGroup(Device* device,
const BindGroupDescriptor* descriptor) {
return AcquireRef(mBindGroupAllocator.Allocate(device, descriptor));

View File

@ -33,7 +33,7 @@ namespace dawn_native { namespace opengl {
void DeallocateBindGroup(BindGroup* bindGroup);
private:
~BindGroupLayout() override = default;
~BindGroupLayout() override;
SlabAllocator<BindGroup> mBindGroupAllocator;
};

View File

@ -161,6 +161,7 @@ namespace dawn_native { namespace vulkan {
device->fn.DestroyDescriptorSetLayout(device->GetVkDevice(), mHandle, nullptr);
mHandle = VK_NULL_HANDLE;
}
DestroyApiObject();
}
VkDescriptorSetLayout BindGroupLayout::GetHandle() const {

View File

@ -126,10 +126,29 @@ dawn_json_generator("mock_webgpu_gen") {
]
}
# Source code for mocks used for unit testing are separated from the rest of
# sources so that they aren't included in non-test builds.
source_set("dawn_native_mocks_sources") {
testonly = true
deps = [
":gmock_and_gtest",
"${dawn_root}/src/dawn_native:dawn_native_sources",
"${dawn_root}/src/dawn_native:dawn_native_static",
"${dawn_root}/src/utils:dawn_utils",
]
sources = [
"unittests/native/mocks/BindGroupLayoutMock.h",
"unittests/native/mocks/DeviceMock.h",
]
}
test("dawn_unittests") {
configs += [ "${dawn_root}/src/common:dawn_internal" ]
deps = [
":dawn_native_mocks_sources",
":gmock_and_gtest",
":mock_webgpu_gen",
"${dawn_root}/src/common",
@ -150,6 +169,8 @@ test("dawn_unittests") {
"${dawn_root}/src/dawn_wire/client/ClientMemoryTransferService_mock.h",
"${dawn_root}/src/dawn_wire/server/ServerMemoryTransferService_mock.cpp",
"${dawn_root}/src/dawn_wire/server/ServerMemoryTransferService_mock.h",
"DawnNativeTest.cpp",
"DawnNativeTest.h",
"MockCallback.h",
"ToggleParser.cpp",
"ToggleParser.h",
@ -188,6 +209,7 @@ test("dawn_unittests") {
"unittests/SystemUtilsTests.cpp",
"unittests/ToBackendTests.cpp",
"unittests/TypedIntegerTests.cpp",
"unittests/native/DestroyObjectTests.cpp",
"unittests/validation/BindGroupValidationTests.cpp",
"unittests/validation/BufferValidationTests.cpp",
"unittests/validation/CommandBufferValidationTests.cpp",

View File

@ -0,0 +1,30 @@
// 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.
#include <gtest/gtest.h>
#include "absl/strings/str_cat.h"
#include "dawn_native/ErrorData.h"
namespace dawn_native {
void AddFatalDawnFailure(const char* expression, const ErrorData* error) {
const auto& backtrace = error->GetBacktrace();
GTEST_MESSAGE_AT_(
backtrace.at(0).file, backtrace.at(0).line,
absl::StrCat(expression, " returned error: ", error->GetMessage()).c_str(),
::testing::TestPartResult::kFatalFailure);
}
} // namespace dawn_native

View File

@ -0,0 +1,32 @@
// 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_DAWNNATIVETEST_H_
#define TESTS_DAWNNATIVETEST_H_
#include <gtest/gtest.h>
#include "dawn_native/ErrorData.h"
namespace dawn_native {
// This is similar to DAWN_TRY_ASSIGN but produces a fatal GTest error if EXPR is an error.
#define DAWN_ASSERT_AND_ASSIGN(VAR, EXPR) \
DAWN_TRY_ASSIGN_WITH_CLEANUP(VAR, EXPR, {}, AddFatalDawnFailure(#EXPR, error.get()))
void AddFatalDawnFailure(const char* expression, const ErrorData* error);
} // namespace dawn_native
#endif // TESTS_DAWNNATIVETEST_H_

View File

@ -243,6 +243,78 @@ namespace {
ASSERT_EQ(errorData->GetMessage(), dummyErrorMessage);
}
// Check DAWN_TRY_ASSIGN handles successes correctly.
TEST(ErrorTests, TRY_RESULT_CLEANUP_Success) {
auto ReturnSuccess = []() -> ResultOrError<int*> { return &dummySuccess; };
// We need to check that DAWN_TRY_ASSIGN_WITH_CLEANUP doesn't return on successes and the
// cleanup is not called.
bool tryReturned = true;
bool tryCleanup = false;
auto Try = [ReturnSuccess, &tryReturned, &tryCleanup]() -> ResultOrError<int*> {
int* result = nullptr;
DAWN_TRY_ASSIGN_WITH_CLEANUP(result, ReturnSuccess(), { tryCleanup = true; });
tryReturned = false;
EXPECT_EQ(result, &dummySuccess);
return result;
};
ResultOrError<int*> result = Try();
ASSERT_TRUE(result.IsSuccess());
ASSERT_FALSE(tryReturned);
ASSERT_FALSE(tryCleanup);
ASSERT_EQ(result.AcquireSuccess(), &dummySuccess);
}
// Check DAWN_TRY_ASSIGN handles cleanups.
TEST(ErrorTests, TRY_RESULT_CLEANUP_Cleanup) {
auto ReturnError = []() -> ResultOrError<int*> {
return DAWN_VALIDATION_ERROR(dummyErrorMessage);
};
// We need to check that DAWN_TRY_ASSIGN_WITH_CLEANUP calls cleanup when error.
bool tryCleanup = false;
auto Try = [ReturnError, &tryCleanup]() -> ResultOrError<int*> {
int* result = nullptr;
DAWN_TRY_ASSIGN_WITH_CLEANUP(result, ReturnError(), { tryCleanup = true; });
DAWN_UNUSED(result);
// DAWN_TRY_ASSIGN_WITH_CLEANUP should return before this point
EXPECT_FALSE(true);
return &dummySuccess;
};
ResultOrError<int*> result = Try();
ASSERT_TRUE(result.IsError());
std::unique_ptr<ErrorData> errorData = result.AcquireError();
ASSERT_EQ(errorData->GetMessage(), dummyErrorMessage);
ASSERT_TRUE(tryCleanup);
}
// Check DAWN_TRY_ASSIGN can override return value when needed.
TEST(ErrorTests, TRY_RESULT_CLEANUP_OverrideReturn) {
auto ReturnError = []() -> ResultOrError<int*> {
return DAWN_VALIDATION_ERROR(dummyErrorMessage);
};
auto Try = [ReturnError]() -> bool {
int* result = nullptr;
DAWN_TRY_ASSIGN_WITH_CLEANUP(result, ReturnError(), {}, true);
DAWN_UNUSED(result);
// DAWN_TRY_ASSIGN_WITH_CLEANUP should return before this point
EXPECT_FALSE(true);
return false;
};
bool result = Try();
ASSERT_TRUE(result);
}
// Check a MaybeError can be DAWN_TRIED in a function that returns an ResultOrError
// Check DAWN_TRY handles errors correctly.
TEST(ErrorTests, TRY_ConversionToErrorOrResult) {

View File

@ -0,0 +1,73 @@
// 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.
#include <gtest/gtest.h>
#include "dawn_native/Toggles.h"
#include "mocks/BindGroupLayoutMock.h"
#include "mocks/DeviceMock.h"
#include "tests/DawnNativeTest.h"
namespace dawn_native { namespace {
using ::testing::ByMove;
using ::testing::InSequence;
using ::testing::Return;
TEST(DestroyObjectTests, BindGroupLayout) {
// Skipping validation on descriptors as coverage for validation is already present.
DeviceMock device;
device.SetToggle(Toggle::SkipValidation, true);
BindGroupLayoutMock* bindGroupLayoutMock = new BindGroupLayoutMock(&device);
EXPECT_CALL(*bindGroupLayoutMock, DestroyApiObjectImpl).Times(1);
BindGroupLayoutDescriptor desc = {};
Ref<BindGroupLayoutBase> bindGroupLayout;
EXPECT_CALL(device, CreateBindGroupLayoutImpl)
.WillOnce(Return(ByMove(AcquireRef(bindGroupLayoutMock))));
DAWN_ASSERT_AND_ASSIGN(bindGroupLayout, device.CreateBindGroupLayout(&desc));
EXPECT_TRUE(bindGroupLayout->IsAlive());
EXPECT_TRUE(bindGroupLayout->IsCachedReference());
bindGroupLayout->DestroyApiObject();
EXPECT_FALSE(bindGroupLayout->IsAlive());
}
// Destroying the objects on the device should result in all created objects being destroyed in
// order.
TEST(DestroyObjectTests, DestroyObjects) {
DeviceMock device;
device.SetToggle(Toggle::SkipValidation, true);
BindGroupLayoutMock* bindGroupLayoutMock = new BindGroupLayoutMock(&device);
{
InSequence seq;
EXPECT_CALL(*bindGroupLayoutMock, DestroyApiObjectImpl).Times(1);
}
BindGroupLayoutDescriptor desc = {};
Ref<BindGroupLayoutBase> bindGroupLayout;
EXPECT_CALL(device, CreateBindGroupLayoutImpl)
.WillOnce(Return(ByMove(AcquireRef(bindGroupLayoutMock))));
DAWN_ASSERT_AND_ASSIGN(bindGroupLayout, device.CreateBindGroupLayout(&desc));
EXPECT_TRUE(bindGroupLayout->IsAlive());
EXPECT_TRUE(bindGroupLayout->IsCachedReference());
device.DestroyObjects();
EXPECT_FALSE(bindGroupLayout->IsAlive());
}
}} // namespace dawn_native::

View File

@ -0,0 +1,38 @@
// 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_BINDGROUPLAYOUT_MOCK_H_
#define TESTS_UNITTESTS_NATIVE_MOCKS_BINDGROUPLAYOUT_MOCK_H_
#include "dawn_native/BindGroupLayout.h"
#include "dawn_native/Device.h"
#include <gmock/gmock.h>
namespace dawn_native {
class BindGroupLayoutMock final : public BindGroupLayoutBase {
public:
BindGroupLayoutMock(DeviceBase* device) : BindGroupLayoutBase(device) {
}
~BindGroupLayoutMock() override {
DestroyApiObject();
}
MOCK_METHOD(void, DestroyApiObjectImpl, (), (override));
};
} // namespace dawn_native
#endif // TESTS_UNITTESTS_NATIVE_MOCKS_BINDGROUPLAYOUT_MOCK_H_

View File

@ -0,0 +1,116 @@
// 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_DEVICE_MOCK_H_
#define TESTS_UNITTESTS_NATIVE_MOCKS_DEVICE_MOCK_H_
#include "dawn_native/Device.h"
#include <gmock/gmock.h>
namespace dawn_native {
class DeviceMock : public DeviceBase {
public:
// Exposes some protected functions for testing purposes.
using DeviceBase::DestroyObjects;
using DeviceBase::SetToggle;
MOCK_METHOD(ResultOrError<Ref<CommandBufferBase>>,
CreateCommandBuffer,
(CommandEncoder*, const CommandBufferDescriptor*),
(override));
MOCK_METHOD(ResultOrError<std::unique_ptr<StagingBufferBase>>,
CreateStagingBuffer,
(size_t),
(override));
MOCK_METHOD(MaybeError,
CopyFromStagingToBuffer,
(StagingBufferBase*, uint64_t, BufferBase*, uint64_t, uint64_t),
(override));
MOCK_METHOD(
MaybeError,
CopyFromStagingToTexture,
(const StagingBufferBase*, const TextureDataLayout&, TextureCopy*, const Extent3D&),
(override));
MOCK_METHOD(uint32_t, GetOptimalBytesPerRowAlignment, (), (const, override));
MOCK_METHOD(uint64_t, GetOptimalBufferToTextureCopyOffsetAlignment, (), (const, override));
MOCK_METHOD(float, GetTimestampPeriodInNS, (), (const, override));
MOCK_METHOD(ResultOrError<Ref<BindGroupBase>>,
CreateBindGroupImpl,
(const BindGroupDescriptor*),
(override));
MOCK_METHOD(ResultOrError<Ref<BindGroupLayoutBase>>,
CreateBindGroupLayoutImpl,
(const BindGroupLayoutDescriptor*, PipelineCompatibilityToken),
(override));
MOCK_METHOD(ResultOrError<Ref<BufferBase>>,
CreateBufferImpl,
(const BufferDescriptor*),
(override));
MOCK_METHOD(ResultOrError<Ref<ComputePipelineBase>>,
CreateComputePipelineImpl,
(const ComputePipelineDescriptor*),
(override));
MOCK_METHOD(ResultOrError<Ref<PipelineLayoutBase>>,
CreatePipelineLayoutImpl,
(const PipelineLayoutDescriptor*),
(override));
MOCK_METHOD(ResultOrError<Ref<QuerySetBase>>,
CreateQuerySetImpl,
(const QuerySetDescriptor*),
(override));
MOCK_METHOD(Ref<RenderPipelineBase>,
CreateUninitializedRenderPipelineImpl,
(const RenderPipelineDescriptor*),
(override));
MOCK_METHOD(ResultOrError<Ref<SamplerBase>>,
CreateSamplerImpl,
(const SamplerDescriptor*),
(override));
MOCK_METHOD(ResultOrError<Ref<ShaderModuleBase>>,
CreateShaderModuleImpl,
(const ShaderModuleDescriptor*, ShaderModuleParseResult*),
(override));
MOCK_METHOD(ResultOrError<Ref<SwapChainBase>>,
CreateSwapChainImpl,
(const SwapChainDescriptor*),
(override));
MOCK_METHOD(ResultOrError<Ref<NewSwapChainBase>>,
CreateSwapChainImpl,
(Surface*, NewSwapChainBase*, const SwapChainDescriptor*),
(override));
MOCK_METHOD(ResultOrError<Ref<TextureBase>>,
CreateTextureImpl,
(const TextureDescriptor*),
(override));
MOCK_METHOD(ResultOrError<Ref<TextureViewBase>>,
CreateTextureViewImpl,
(TextureBase*, const TextureViewDescriptor*),
(override));
MOCK_METHOD(MaybeError, TickImpl, (), (override));
MOCK_METHOD(ResultOrError<ExecutionSerial>, CheckAndUpdateCompletedSerials, (), (override));
MOCK_METHOD(void, DestroyImpl, (), (override));
MOCK_METHOD(MaybeError, WaitForIdleForDestruction, (), (override));
};
} // namespace dawn_native
#endif // TESTS_UNITTESTS_NATIVE_MOCKS_DEVICE_MOCK_H_