Refactors native mock classes to be more like the Null device.

- Plumbs all descriptors through so that the objects act much more like
  a real implementation.
- Lots of changes to DestroyObjectTests.cpp to update usages and test
  through the APIs when applicable.
- Put in defaults for the mock device and make it as easy to use as
  possible.

Change-Id: I85b243a18ec1872aff0172549aec0f599967ea0e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/119821
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Loko Kung <lokokung@google.com>
This commit is contained in:
Loko Kung 2023-02-22 20:38:37 +00:00 committed by Dawn LUCI CQ
parent 54a104e28f
commit f35f1ff98c
62 changed files with 1505 additions and 902 deletions

View File

@ -456,10 +456,6 @@ BindGroupBase::BindGroupBase(DeviceBase* device,
GetObjectTrackingList()->Track(this); GetObjectTrackingList()->Track(this);
} }
BindGroupBase::BindGroupBase(DeviceBase* device) : ApiObjectBase(device, kLabelNotImplemented) {
GetObjectTrackingList()->Track(this);
}
BindGroupBase::~BindGroupBase() = default; BindGroupBase::~BindGroupBase() = default;
void BindGroupBase::DestroyImpl() { void BindGroupBase::DestroyImpl() {

View File

@ -76,8 +76,6 @@ class BindGroupBase : public ApiObjectBase {
static_assert(std::is_base_of<BindGroupBase, Derived>::value); static_assert(std::is_base_of<BindGroupBase, Derived>::value);
} }
// Constructor used only for mocking and testing.
explicit BindGroupBase(DeviceBase* device);
void DestroyImpl() override; void DestroyImpl() override;
~BindGroupBase() override; ~BindGroupBase() override;

View File

@ -493,11 +493,6 @@ BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device,
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag) BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: ApiObjectBase(device, tag) {} : ApiObjectBase(device, tag) {}
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device)
: ApiObjectBase(device, kLabelNotImplemented) {
GetObjectTrackingList()->Track(this);
}
BindGroupLayoutBase::~BindGroupLayoutBase() = default; BindGroupLayoutBase::~BindGroupLayoutBase() = default;
void BindGroupLayoutBase::DestroyImpl() { void BindGroupLayoutBase::DestroyImpl() {

View File

@ -135,8 +135,6 @@ class BindGroupLayoutBase : public ApiObjectBase, public CachedObject {
std::string EntriesToString() const; std::string EntriesToString() const;
protected: protected:
// Constructor used only for mocking and testing.
explicit BindGroupLayoutBase(DeviceBase* device);
void DestroyImpl() override; void DestroyImpl() override;
template <typename BindGroup> template <typename BindGroup>

View File

@ -222,11 +222,6 @@ BufferBase::BufferBase(DeviceBase* device,
} }
} }
BufferBase::BufferBase(DeviceBase* device, BufferState state)
: ApiObjectBase(device, kLabelNotImplemented), mState(state) {
GetObjectTrackingList()->Track(this);
}
BufferBase::~BufferBase() { BufferBase::~BufferBase() {
ASSERT(mState == BufferState::Unmapped || mState == BufferState::Destroyed); ASSERT(mState == BufferState::Unmapped || mState == BufferState::Destroyed);
} }

View File

@ -96,8 +96,6 @@ class BufferBase : public ApiObjectBase {
protected: protected:
BufferBase(DeviceBase* device, const BufferDescriptor* descriptor); BufferBase(DeviceBase* device, const BufferDescriptor* descriptor);
BufferBase(DeviceBase* device, const BufferDescriptor* descriptor, ObjectBase::ErrorTag tag); BufferBase(DeviceBase* device, const BufferDescriptor* descriptor, ObjectBase::ErrorTag tag);
// Constructor used only for mocking and testing.
BufferBase(DeviceBase* device, BufferState state);
void DestroyImpl() override; void DestroyImpl() override;

View File

@ -37,7 +37,7 @@ size_t CachedObject::GetContentHash() const {
} }
void CachedObject::SetContentHash(size_t contentHash) { void CachedObject::SetContentHash(size_t contentHash) {
ASSERT(!mIsContentHashInitialized); ASSERT(!mIsContentHashInitialized || contentHash == mContentHash);
mContentHash = contentHash; mContentHash = contentHash;
mIsContentHashInitialized = true; mIsContentHashInitialized = true;
} }

View File

@ -33,11 +33,6 @@ CommandBufferBase::CommandBufferBase(CommandEncoder* encoder,
GetObjectTrackingList()->Track(this); GetObjectTrackingList()->Track(this);
} }
CommandBufferBase::CommandBufferBase(DeviceBase* device)
: ApiObjectBase(device, kLabelNotImplemented) {
GetObjectTrackingList()->Track(this);
}
CommandBufferBase::CommandBufferBase(DeviceBase* device, ObjectBase::ErrorTag tag) CommandBufferBase::CommandBufferBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: ApiObjectBase(device, tag) {} : ApiObjectBase(device, tag) {}

View File

@ -45,8 +45,6 @@ class CommandBufferBase : public ApiObjectBase {
CommandIterator* GetCommandIteratorForTesting(); CommandIterator* GetCommandIteratorForTesting();
protected: protected:
// Constructor used only for mocking and testing.
explicit CommandBufferBase(DeviceBase* device);
void DestroyImpl() override; void DestroyImpl() override;
CommandIterator mCommands; CommandIterator mCommands;

View File

@ -56,10 +56,6 @@ ComputePipelineBase::ComputePipelineBase(DeviceBase* device,
StreamIn(&mCacheKey, CacheKey::Type::ComputePipeline, device->GetCacheKey()); StreamIn(&mCacheKey, CacheKey::Type::ComputePipeline, device->GetCacheKey());
} }
ComputePipelineBase::ComputePipelineBase(DeviceBase* device) : PipelineBase(device) {
GetObjectTrackingList()->Track(this);
}
ComputePipelineBase::ComputePipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag) ComputePipelineBase::ComputePipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: PipelineBase(device, tag) {} : PipelineBase(device, tag) {}

View File

@ -42,8 +42,6 @@ class ComputePipelineBase : public PipelineBase {
}; };
protected: protected:
// Constructor used only for mocking and testing.
explicit ComputePipelineBase(DeviceBase* device);
void DestroyImpl() override; void DestroyImpl() override;
private: private:

View File

@ -125,6 +125,7 @@ struct LoggingCallbackTask : CallbackTask {
std::string mMessage; std::string mMessage;
void* mUserdata; void* mUserdata;
}; };
} // anonymous namespace
ResultOrError<Ref<PipelineLayoutBase>> ValidateLayoutAndGetComputePipelineDescriptorWithDefaults( ResultOrError<Ref<PipelineLayoutBase>> ValidateLayoutAndGetComputePipelineDescriptorWithDefaults(
DeviceBase* device, DeviceBase* device,
@ -167,8 +168,6 @@ ResultOrError<Ref<PipelineLayoutBase>> ValidateLayoutAndGetRenderPipelineDescrip
return layoutRef; return layoutRef;
} }
} // anonymous namespace
// DeviceBase // DeviceBase
DeviceBase::DeviceBase(AdapterBase* adapter, DeviceBase::DeviceBase(AdapterBase* adapter,
@ -210,7 +209,7 @@ DeviceBase::DeviceBase(AdapterBase* adapter,
} }
DeviceBase::DeviceBase() : mState(State::Alive), mToggles(ToggleStage::Device) { DeviceBase::DeviceBase() : mState(State::Alive), mToggles(ToggleStage::Device) {
mCaches = std::make_unique<DeviceBase::Caches>(); mFormatTable = BuildFormatTable(this);
} }
DeviceBase::~DeviceBase() { DeviceBase::~DeviceBase() {

View File

@ -139,7 +139,7 @@ class DeviceBase : public RefCountedWithExternalCount {
MaybeError ValidateObject(const ApiObjectBase* object) const; MaybeError ValidateObject(const ApiObjectBase* object) const;
AdapterBase* GetAdapter() const; AdapterBase* GetAdapter() const;
dawn::platform::Platform* GetPlatform() const; virtual dawn::platform::Platform* GetPlatform() const;
// Returns the Format corresponding to the wgpu::TextureFormat or an error if the format // Returns the Format corresponding to the wgpu::TextureFormat or an error if the format
// isn't a valid wgpu::TextureFormat or isn't supported by this device. // isn't a valid wgpu::TextureFormat or isn't supported by this device.
@ -582,6 +582,16 @@ class DeviceBase : public RefCountedWithExternalCount {
CacheKey mDeviceCacheKey; CacheKey mDeviceCacheKey;
}; };
ResultOrError<Ref<PipelineLayoutBase>> ValidateLayoutAndGetComputePipelineDescriptorWithDefaults(
DeviceBase* device,
const ComputePipelineDescriptor& descriptor,
ComputePipelineDescriptor* outDescriptor);
ResultOrError<Ref<PipelineLayoutBase>> ValidateLayoutAndGetRenderPipelineDescriptorWithDefaults(
DeviceBase* device,
const RenderPipelineDescriptor& descriptor,
RenderPipelineDescriptor* outDescriptor);
class IgnoreLazyClearCountScope : public NonMovable { class IgnoreLazyClearCountScope : public NonMovable {
public: public:
explicit IgnoreLazyClearCountScope(DeviceBase* device); explicit IgnoreLazyClearCountScope(DeviceBase* device);

View File

@ -137,11 +137,6 @@ ExternalTextureBase::ExternalTextureBase(DeviceBase* device,
GetObjectTrackingList()->Track(this); GetObjectTrackingList()->Track(this);
} }
ExternalTextureBase::ExternalTextureBase(DeviceBase* device)
: ApiObjectBase(device, kLabelNotImplemented), mState(ExternalTextureState::Alive) {
GetObjectTrackingList()->Track(this);
}
// Error external texture cannot be used in bind group. // Error external texture cannot be used in bind group.
ExternalTextureBase::ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag) ExternalTextureBase::ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: ApiObjectBase(device, tag), mState(ExternalTextureState::Destroyed) {} : ApiObjectBase(device, tag), mState(ExternalTextureState::Destroyed) {}

View File

@ -60,18 +60,16 @@ class ExternalTextureBase : public ApiObjectBase {
void APIDestroy(); void APIDestroy();
protected: protected:
// Constructor used only for mocking and testing. ExternalTextureBase(DeviceBase* device, const ExternalTextureDescriptor* descriptor);
explicit ExternalTextureBase(DeviceBase* device);
void DestroyImpl() override; void DestroyImpl() override;
MaybeError Initialize(DeviceBase* device, const ExternalTextureDescriptor* descriptor);
~ExternalTextureBase() override; ~ExternalTextureBase() override;
private: private:
ExternalTextureBase(DeviceBase* device, const ExternalTextureDescriptor* descriptor);
enum class ExternalTextureState { Alive, Destroyed }; enum class ExternalTextureState { Alive, Destroyed };
ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag); ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag);
MaybeError Initialize(DeviceBase* device, const ExternalTextureDescriptor* descriptor);
Ref<TextureBase> mPlaceholderTexture; Ref<TextureBase> mPlaceholderTexture;
Ref<BufferBase> mParamsBuffer; Ref<BufferBase> mParamsBuffer;

View File

@ -197,8 +197,6 @@ PipelineBase::PipelineBase(DeviceBase* device,
} }
} }
PipelineBase::PipelineBase(DeviceBase* device) : ApiObjectBase(device, kLabelNotImplemented) {}
PipelineBase::PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag) PipelineBase::PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: ApiObjectBase(device, tag) {} : ApiObjectBase(device, tag) {}

View File

@ -83,9 +83,6 @@ class PipelineBase : public ApiObjectBase, public CachedObject {
std::vector<StageAndDescriptor> stages); std::vector<StageAndDescriptor> stages);
PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag); PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag);
// Constructor used only for mocking and testing.
explicit PipelineBase(DeviceBase* device);
private: private:
MaybeError ValidateGetBindGroupLayout(BindGroupIndex group); MaybeError ValidateGetBindGroupLayout(BindGroupIndex group);

View File

@ -74,11 +74,6 @@ PipelineLayoutBase::PipelineLayoutBase(DeviceBase* device,
GetObjectTrackingList()->Track(this); GetObjectTrackingList()->Track(this);
} }
PipelineLayoutBase::PipelineLayoutBase(DeviceBase* device)
: ApiObjectBase(device, kLabelNotImplemented) {
GetObjectTrackingList()->Track(this);
}
PipelineLayoutBase::PipelineLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag) PipelineLayoutBase::PipelineLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: ApiObjectBase(device, tag) {} : ApiObjectBase(device, tag) {}

View File

@ -84,8 +84,6 @@ class PipelineLayoutBase : public ApiObjectBase, public CachedObject {
}; };
protected: protected:
// Constructor used only for mocking and testing.
explicit PipelineLayoutBase(DeviceBase* device);
PipelineLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag); PipelineLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag);
void DestroyImpl() override; void DestroyImpl() override;

View File

@ -111,10 +111,6 @@ QuerySetBase::QuerySetBase(DeviceBase* device, const QuerySetDescriptor* descrip
GetObjectTrackingList()->Track(this); GetObjectTrackingList()->Track(this);
} }
QuerySetBase::QuerySetBase(DeviceBase* device) : ApiObjectBase(device, kLabelNotImplemented) {
GetObjectTrackingList()->Track(this);
}
QuerySetBase::QuerySetBase(DeviceBase* device, QuerySetBase::QuerySetBase(DeviceBase* device,
const QuerySetDescriptor* descriptor, const QuerySetDescriptor* descriptor,
ObjectBase::ErrorTag tag) ObjectBase::ErrorTag tag)

View File

@ -52,8 +52,6 @@ class QuerySetBase : public ApiObjectBase {
const QuerySetDescriptor* descriptor, const QuerySetDescriptor* descriptor,
ObjectBase::ErrorTag tag); ObjectBase::ErrorTag tag);
// Constructor used only for mocking and testing.
explicit QuerySetBase(DeviceBase* device);
void DestroyImpl() override; void DestroyImpl() override;
~QuerySetBase() override; ~QuerySetBase() override;

View File

@ -672,10 +672,6 @@ RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
StreamIn(&mCacheKey, CacheKey::Type::RenderPipeline, device->GetCacheKey()); StreamIn(&mCacheKey, CacheKey::Type::RenderPipeline, device->GetCacheKey());
} }
RenderPipelineBase::RenderPipelineBase(DeviceBase* device) : PipelineBase(device) {
GetObjectTrackingList()->Track(this);
}
RenderPipelineBase::RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag) RenderPipelineBase::RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: PipelineBase(device, tag) {} : PipelineBase(device, tag) {}

View File

@ -113,8 +113,6 @@ class RenderPipelineBase : public PipelineBase {
}; };
protected: protected:
// Constructor used only for mocking and testing.
explicit RenderPipelineBase(DeviceBase* device);
void DestroyImpl() override; void DestroyImpl() override;
private: private:

View File

@ -89,10 +89,6 @@ SamplerBase::SamplerBase(DeviceBase* device, const SamplerDescriptor* descriptor
GetObjectTrackingList()->Track(this); GetObjectTrackingList()->Track(this);
} }
SamplerBase::SamplerBase(DeviceBase* device) : ApiObjectBase(device, kLabelNotImplemented) {
GetObjectTrackingList()->Track(this);
}
SamplerBase::SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag) SamplerBase::SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: ApiObjectBase(device, tag) {} : ApiObjectBase(device, tag) {}

View File

@ -53,8 +53,6 @@ class SamplerBase : public ApiObjectBase, public CachedObject {
uint16_t GetMaxAnisotropy() const { return mMaxAnisotropy; } uint16_t GetMaxAnisotropy() const { return mMaxAnisotropy; }
protected: protected:
// Constructor used only for mocking and testing.
explicit SamplerBase(DeviceBase* device);
void DestroyImpl() override; void DestroyImpl() override;
private: private:

View File

@ -1111,11 +1111,6 @@ ShaderModuleBase::ShaderModuleBase(DeviceBase* device, const ShaderModuleDescrip
GetObjectTrackingList()->Track(this); GetObjectTrackingList()->Track(this);
} }
ShaderModuleBase::ShaderModuleBase(DeviceBase* device)
: ApiObjectBase(device, kLabelNotImplemented) {
GetObjectTrackingList()->Track(this);
}
ShaderModuleBase::ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag) ShaderModuleBase::ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: ApiObjectBase(device, tag), mType(Type::Undefined) {} : ApiObjectBase(device, tag), mType(Type::Undefined) {}

View File

@ -286,8 +286,6 @@ class ShaderModuleBase : public ApiObjectBase, public CachedObject {
OwnedCompilationMessages* GetCompilationMessages() const; OwnedCompilationMessages* GetCompilationMessages() const;
protected: protected:
// Constructor used only for mocking and testing.
explicit ShaderModuleBase(DeviceBase* device);
void DestroyImpl() override; void DestroyImpl() override;
MaybeError InitializeBase(ShaderModuleParseResult* parseResult, MaybeError InitializeBase(ShaderModuleParseResult* parseResult,

View File

@ -581,11 +581,6 @@ TextureBase::~TextureBase() = default;
static constexpr Format kUnusedFormat; static constexpr Format kUnusedFormat;
TextureBase::TextureBase(DeviceBase* device, TextureState state)
: ApiObjectBase(device, kLabelNotImplemented), mFormat(kUnusedFormat), mState(state) {
GetObjectTrackingList()->Track(this);
}
TextureBase::TextureBase(DeviceBase* device, TextureBase::TextureBase(DeviceBase* device,
const TextureDescriptor* descriptor, const TextureDescriptor* descriptor,
ObjectBase::ErrorTag tag) ObjectBase::ErrorTag tag)
@ -854,13 +849,6 @@ TextureViewBase::TextureViewBase(TextureBase* texture, const TextureViewDescript
GetObjectTrackingList()->Track(this); GetObjectTrackingList()->Track(this);
} }
TextureViewBase::TextureViewBase(TextureBase* texture)
: ApiObjectBase(texture->GetDevice(), kLabelNotImplemented),
mTexture(texture),
mFormat(kUnusedFormat) {
GetObjectTrackingList()->Track(this);
}
TextureViewBase::TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag) TextureViewBase::TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: ApiObjectBase(device, tag), mFormat(kUnusedFormat) {} : ApiObjectBase(device, tag), mFormat(kUnusedFormat) {}

View File

@ -108,8 +108,6 @@ class TextureBase : public ApiObjectBase {
protected: protected:
TextureBase(DeviceBase* device, const TextureDescriptor* descriptor, TextureState state); TextureBase(DeviceBase* device, const TextureDescriptor* descriptor, TextureState state);
// Constructor used only for mocking and testing.
TextureBase(DeviceBase* device, TextureState state);
~TextureBase() override; ~TextureBase() override;
void DestroyImpl() override; void DestroyImpl() override;
@ -159,8 +157,6 @@ class TextureViewBase : public ApiObjectBase {
const SubresourceRange& GetSubresourceRange() const; const SubresourceRange& GetSubresourceRange() const;
protected: protected:
// Constructor used only for mocking and testing.
explicit TextureViewBase(TextureBase* texture);
void DestroyImpl() override; void DestroyImpl() override;
private: private:

View File

@ -191,6 +191,7 @@ source_set("native_mocks_sources") {
deps = [ deps = [
":gmock_and_gtest", ":gmock_and_gtest",
"${dawn_root}/src/dawn:proc",
"${dawn_root}/src/dawn/native:sources", "${dawn_root}/src/dawn/native:sources",
"${dawn_root}/src/dawn/native:static", "${dawn_root}/src/dawn/native:static",
"${dawn_root}/src/dawn/utils", "${dawn_root}/src/dawn/utils",
@ -210,6 +211,9 @@ source_set("native_mocks_sources") {
"unittests/native/mocks/CommandBufferMock.h", "unittests/native/mocks/CommandBufferMock.h",
"unittests/native/mocks/ComputePipelineMock.cpp", "unittests/native/mocks/ComputePipelineMock.cpp",
"unittests/native/mocks/ComputePipelineMock.h", "unittests/native/mocks/ComputePipelineMock.h",
"unittests/native/mocks/DawnMockTest.cpp",
"unittests/native/mocks/DawnMockTest.h",
"unittests/native/mocks/DeviceMock.cpp",
"unittests/native/mocks/DeviceMock.h", "unittests/native/mocks/DeviceMock.h",
"unittests/native/mocks/ExternalTextureMock.cpp", "unittests/native/mocks/ExternalTextureMock.cpp",
"unittests/native/mocks/ExternalTextureMock.h", "unittests/native/mocks/ExternalTextureMock.h",
@ -217,6 +221,8 @@ source_set("native_mocks_sources") {
"unittests/native/mocks/PipelineLayoutMock.h", "unittests/native/mocks/PipelineLayoutMock.h",
"unittests/native/mocks/QuerySetMock.cpp", "unittests/native/mocks/QuerySetMock.cpp",
"unittests/native/mocks/QuerySetMock.h", "unittests/native/mocks/QuerySetMock.h",
"unittests/native/mocks/QueueMock.cpp",
"unittests/native/mocks/QueueMock.h",
"unittests/native/mocks/RenderPipelineMock.cpp", "unittests/native/mocks/RenderPipelineMock.cpp",
"unittests/native/mocks/RenderPipelineMock.h", "unittests/native/mocks/RenderPipelineMock.h",
"unittests/native/mocks/SamplerMock.cpp", "unittests/native/mocks/SamplerMock.cpp",

View File

@ -12,27 +12,45 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "dawn/tests/DawnNativeTest.h" #include <gtest/gtest.h>
#include "dawn/native/CreatePipelineAsyncTask.h" #include "dawn/native/CreatePipelineAsyncTask.h"
#include "dawn/utils/WGPUHelpers.h"
#include "mocks/ComputePipelineMock.h" #include "mocks/ComputePipelineMock.h"
#include "mocks/DawnMockTest.h"
#include "mocks/RenderPipelineMock.h" #include "mocks/RenderPipelineMock.h"
class CreatePipelineAsyncTaskTests : public DawnNativeTest {}; namespace dawn::native {
namespace {
using ::testing::Test;
static constexpr std::string_view kComputeShader = R"(
@compute @workgroup_size(1) fn main() {}
)";
static constexpr std::string_view kVertexShader = R"(
@vertex fn main() -> @builtin(position) vec4f {
return vec4f(0.0, 0.0, 0.0, 1.0);
}
)";
class CreatePipelineAsyncTaskTests : public DawnMockTest {};
// A regression test for a null pointer issue in CreateRenderPipelineAsyncTask::Run(). // A regression test for a null pointer issue in CreateRenderPipelineAsyncTask::Run().
// See crbug.com/dawn/1310 for more details. // See crbug.com/dawn/1310 for more details.
TEST_F(CreatePipelineAsyncTaskTests, InitializationValidationErrorInCreateRenderPipelineAsync) { TEST_F(CreatePipelineAsyncTaskTests, InitializationValidationErrorInCreateRenderPipelineAsync) {
dawn::native::DeviceBase* deviceBase = wgpu::RenderPipelineDescriptor desc = {};
reinterpret_cast<dawn::native::DeviceBase*>(device.Get()); desc.vertex.module = utils::CreateShaderModule(device, kVertexShader.data());
Ref<dawn::native::RenderPipelineMock> renderPipelineMock = desc.vertex.entryPoint = "main";
AcquireRef(new dawn::native::RenderPipelineMock(deviceBase)); Ref<RenderPipelineMock> renderPipelineMock =
RenderPipelineMock::Create(mDeviceMock, FromCppAPI(&desc));
ON_CALL(*renderPipelineMock.Get(), Initialize) ON_CALL(*renderPipelineMock.Get(), Initialize)
.WillByDefault(testing::Return(testing::ByMove( .WillByDefault(testing::Return(testing::ByMove(
DAWN_MAKE_ERROR(dawn::native::InternalErrorType::Validation, "Initialization Error")))); DAWN_MAKE_ERROR(InternalErrorType::Validation, "Initialization Error"))));
dawn::native::CreateRenderPipelineAsyncTask asyncTask( CreateRenderPipelineAsyncTask asyncTask(
renderPipelineMock, renderPipelineMock,
[](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline returnPipeline, [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline returnPipeline,
const char* message, void* userdata) { const char* message, void* userdata) {
@ -50,10 +68,11 @@ TEST_F(CreatePipelineAsyncTaskTests, InitializationValidationErrorInCreateRender
// Test that Internal error are converted to the InternalError status in async pipeline creation // Test that Internal error are converted to the InternalError status in async pipeline creation
// callbacks. // callbacks.
TEST_F(CreatePipelineAsyncTaskTests, InitializationInternalErrorInCreateRenderPipelineAsync) { TEST_F(CreatePipelineAsyncTaskTests, InitializationInternalErrorInCreateRenderPipelineAsync) {
dawn::native::DeviceBase* deviceBase = wgpu::RenderPipelineDescriptor desc = {};
reinterpret_cast<dawn::native::DeviceBase*>(device.Get()); desc.vertex.module = utils::CreateShaderModule(device, kVertexShader.data());
Ref<dawn::native::RenderPipelineMock> renderPipelineMock = desc.vertex.entryPoint = "main";
AcquireRef(new dawn::native::RenderPipelineMock(deviceBase)); Ref<RenderPipelineMock> renderPipelineMock =
RenderPipelineMock::Create(mDeviceMock, FromCppAPI(&desc));
ON_CALL(*renderPipelineMock.Get(), Initialize) ON_CALL(*renderPipelineMock.Get(), Initialize)
.WillByDefault(testing::Return(testing::ByMove( .WillByDefault(testing::Return(testing::ByMove(
@ -77,16 +96,17 @@ TEST_F(CreatePipelineAsyncTaskTests, InitializationInternalErrorInCreateRenderPi
// A regression test for a null pointer issue in CreateComputePipelineAsyncTask::Run(). // A regression test for a null pointer issue in CreateComputePipelineAsyncTask::Run().
// See crbug.com/dawn/1310 for more details. // See crbug.com/dawn/1310 for more details.
TEST_F(CreatePipelineAsyncTaskTests, InitializationValidationErrorInCreateComputePipelineAsync) { TEST_F(CreatePipelineAsyncTaskTests, InitializationValidationErrorInCreateComputePipelineAsync) {
dawn::native::DeviceBase* deviceBase = wgpu::ComputePipelineDescriptor desc = {};
reinterpret_cast<dawn::native::DeviceBase*>(device.Get()); desc.compute.module = utils::CreateShaderModule(device, kComputeShader.data());
Ref<dawn::native::ComputePipelineMock> computePipelineMock = desc.compute.entryPoint = "main";
AcquireRef(new dawn::native::ComputePipelineMock(deviceBase)); Ref<ComputePipelineMock> computePipelineMock =
ComputePipelineMock::Create(mDeviceMock, FromCppAPI(&desc));
ON_CALL(*computePipelineMock.Get(), Initialize) ON_CALL(*computePipelineMock.Get(), Initialize)
.WillByDefault(testing::Return(testing::ByMove( .WillByDefault(testing::Return(testing::ByMove(
DAWN_MAKE_ERROR(dawn::native::InternalErrorType::Validation, "Initialization Error")))); DAWN_MAKE_ERROR(InternalErrorType::Validation, "Initialization Error"))));
dawn::native::CreateComputePipelineAsyncTask asyncTask( CreateComputePipelineAsyncTask asyncTask(
computePipelineMock, computePipelineMock,
[](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline returnPipeline, [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline returnPipeline,
const char* message, void* userdata) { const char* message, void* userdata) {
@ -104,10 +124,11 @@ TEST_F(CreatePipelineAsyncTaskTests, InitializationValidationErrorInCreateComput
// Test that Internal error are converted to the InternalError status in async pipeline creation // Test that Internal error are converted to the InternalError status in async pipeline creation
// callbacks. // callbacks.
TEST_F(CreatePipelineAsyncTaskTests, InitializationInternalErrorInCreateComputePipelineAsync) { TEST_F(CreatePipelineAsyncTaskTests, InitializationInternalErrorInCreateComputePipelineAsync) {
dawn::native::DeviceBase* deviceBase = wgpu::ComputePipelineDescriptor desc = {};
reinterpret_cast<dawn::native::DeviceBase*>(device.Get()); desc.compute.module = utils::CreateShaderModule(device, kComputeShader.data());
Ref<dawn::native::ComputePipelineMock> computePipelineMock = desc.compute.entryPoint = "main";
AcquireRef(new dawn::native::ComputePipelineMock(deviceBase)); Ref<ComputePipelineMock> computePipelineMock =
ComputePipelineMock::Create(mDeviceMock, FromCppAPI(&desc));
ON_CALL(*computePipelineMock.Get(), Initialize) ON_CALL(*computePipelineMock.Get(), Initialize)
.WillByDefault(testing::Return(testing::ByMove( .WillByDefault(testing::Return(testing::ByMove(
@ -127,3 +148,6 @@ TEST_F(CreatePipelineAsyncTaskTests, InitializationInternalErrorInCreateComputeP
EXPECT_CALL(*computePipelineMock.Get(), DestroyImpl).Times(1); EXPECT_CALL(*computePipelineMock.Get(), DestroyImpl).Times(1);
} }
} // namespace
} // namespace dawn::native

File diff suppressed because it is too large Load Diff

View File

@ -16,10 +16,15 @@
namespace dawn::native { namespace dawn::native {
BindGroupLayoutMock::BindGroupLayoutMock(DeviceBase* device) : BindGroupLayoutBase(device) { BindGroupLayoutMock::BindGroupLayoutMock(DeviceMock* device,
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken)
: BindGroupLayoutBase(device, descriptor, pipelineCompatibilityToken) {
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { ON_CALL(*this, DestroyImpl).WillByDefault([this]() {
this->BindGroupLayoutBase::DestroyImpl(); this->BindGroupLayoutBase::DestroyImpl();
}); });
SetContentHash(ComputeContentHash());
} }
BindGroupLayoutMock::~BindGroupLayoutMock() = default; BindGroupLayoutMock::~BindGroupLayoutMock() = default;

View File

@ -18,13 +18,16 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/BindGroupLayout.h" #include "dawn/native/BindGroupLayout.h"
#include "dawn/native/Device.h" #include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class BindGroupLayoutMock final : public BindGroupLayoutBase { class BindGroupLayoutMock : public BindGroupLayoutBase {
public: public:
explicit BindGroupLayoutMock(DeviceBase* device); BindGroupLayoutMock(
DeviceMock* device,
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken = PipelineCompatibilityToken(0));
~BindGroupLayoutMock() override; ~BindGroupLayoutMock() override;
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));

View File

@ -16,7 +16,9 @@
namespace dawn::native { namespace dawn::native {
BindGroupMock::BindGroupMock(DeviceBase* device) : BindGroupBase(device) { BindGroupMock::BindGroupMock(DeviceMock* device, const BindGroupDescriptor* descriptor)
: BindGroupDataHolder(descriptor->layout->GetBindingDataSize()),
BindGroupBase(device, descriptor, mBindingDataAllocation) {
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->BindGroupBase::DestroyImpl(); }); ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->BindGroupBase::DestroyImpl(); });
} }

View File

@ -18,13 +18,14 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/BindGroup.h" #include "dawn/native/BindGroup.h"
#include "dawn/native/Device.h" #include "dawn/native/null/DeviceNull.h"
#include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class BindGroupMock : public BindGroupBase { class BindGroupMock : private null::BindGroupDataHolder, public BindGroupBase {
public: public:
explicit BindGroupMock(DeviceBase* device); BindGroupMock(DeviceMock* device, const BindGroupDescriptor* descriptor);
~BindGroupMock() override; ~BindGroupMock() override;
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));

View File

@ -16,8 +16,8 @@
namespace dawn::native { namespace dawn::native {
BufferMock::BufferMock(DeviceBase* device, BufferBase::BufferState state) BufferMock::BufferMock(DeviceMock* device, const BufferDescriptor* descriptor)
: BufferBase(device, state) { : BufferBase(device, descriptor) {
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->BufferBase::DestroyImpl(); }); ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->BufferBase::DestroyImpl(); });
} }

View File

@ -18,13 +18,13 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/Buffer.h" #include "dawn/native/Buffer.h"
#include "dawn/native/Device.h" #include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class BufferMock : public BufferBase { class BufferMock : public BufferBase {
public: public:
BufferMock(DeviceBase* device, BufferBase::BufferState state); BufferMock(DeviceMock* device, const BufferDescriptor* descriptor);
~BufferMock() override; ~BufferMock() override;
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));

View File

@ -14,9 +14,18 @@
#include "dawn/tests/unittests/native/mocks/CommandBufferMock.h" #include "dawn/tests/unittests/native/mocks/CommandBufferMock.h"
#include "dawn/native/CommandEncoder.h"
namespace dawn::native { namespace dawn::native {
CommandBufferMock::CommandBufferMock(DeviceBase* device) : CommandBufferBase(device) { CommandBufferMock::CommandBufferMock(DeviceMock* device,
CommandEncoder* encoder,
const CommandBufferDescriptor* descriptor)
: CommandBufferBase(encoder, descriptor) {
// Make sure that the command encoder was also created using the mock device since it is not
// directly passed in.
ASSERT(device == encoder->GetDevice());
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->CommandBufferBase::DestroyImpl(); }); ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->CommandBufferBase::DestroyImpl(); });
} }

View File

@ -18,13 +18,15 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/CommandBuffer.h" #include "dawn/native/CommandBuffer.h"
#include "dawn/native/Device.h" #include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class CommandBufferMock : public CommandBufferBase { class CommandBufferMock : public CommandBufferBase {
public: public:
explicit CommandBufferMock(DeviceBase* device); CommandBufferMock(DeviceMock* device,
CommandEncoder* encoder,
const CommandBufferDescriptor* descriptor);
~CommandBufferMock() override; ~CommandBufferMock() override;
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));

View File

@ -16,7 +16,12 @@
namespace dawn::native { namespace dawn::native {
ComputePipelineMock::ComputePipelineMock(DeviceBase* device) : ComputePipelineBase(device) { using ::testing::NiceMock;
ComputePipelineMock::ComputePipelineMock(DeviceBase* device,
const ComputePipelineDescriptor* descriptor)
: ComputePipelineBase(device, descriptor) {
ON_CALL(*this, Initialize).WillByDefault([]() -> MaybeError { return {}; });
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { ON_CALL(*this, DestroyImpl).WillByDefault([this]() {
this->ComputePipelineBase::DestroyImpl(); this->ComputePipelineBase::DestroyImpl();
}); });
@ -24,4 +29,14 @@ ComputePipelineMock::ComputePipelineMock(DeviceBase* device) : ComputePipelineBa
ComputePipelineMock::~ComputePipelineMock() = default; ComputePipelineMock::~ComputePipelineMock() = default;
// static
Ref<ComputePipelineMock> ComputePipelineMock::Create(DeviceMock* device,
const ComputePipelineDescriptor* descriptor) {
ComputePipelineDescriptor appliedDescriptor;
Ref<PipelineLayoutBase> layoutRef = ValidateLayoutAndGetComputePipelineDescriptorWithDefaults(
device, *descriptor, &appliedDescriptor)
.AcquireSuccess();
return AcquireRef(new NiceMock<ComputePipelineMock>(device, &appliedDescriptor));
}
} // namespace dawn::native } // namespace dawn::native

View File

@ -18,18 +18,23 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/ComputePipeline.h" #include "dawn/native/ComputePipeline.h"
#include "dawn/native/Device.h" #include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class ComputePipelineMock : public ComputePipelineBase { class ComputePipelineMock : public ComputePipelineBase {
public: public:
explicit ComputePipelineMock(DeviceBase* device); // Creates a compute pipeline given the descriptor.
static Ref<ComputePipelineMock> Create(DeviceMock* device,
const ComputePipelineDescriptor* descriptor);
~ComputePipelineMock() override; ~ComputePipelineMock() override;
MOCK_METHOD(MaybeError, Initialize, (), (override)); MOCK_METHOD(MaybeError, Initialize, (), (override));
MOCK_METHOD(size_t, ComputeContentHash, (), (override));
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));
protected:
ComputePipelineMock(DeviceBase* device, const ComputePipelineDescriptor* descriptor);
}; };
} // namespace dawn::native } // namespace dawn::native

View File

@ -0,0 +1,33 @@
// Copyright 2023 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 "dawn/tests/unittests/native/mocks/DawnMockTest.h"
#include "dawn/dawn_proc.h"
namespace dawn::native {
DawnMockTest::DawnMockTest() {
dawnProcSetProcs(&dawn::native::GetProcs());
mDeviceMock = new ::testing::NiceMock<DeviceMock>();
device = wgpu::Device::Acquire(ToAPI(mDeviceMock));
}
DawnMockTest::~DawnMockTest() {
device = wgpu::Device();
dawnProcSetProcs(nullptr);
}
} // namespace dawn::native

View File

@ -0,0 +1,32 @@
// Copyright 2023 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/tests/unittests/native/mocks/DeviceMock.h"
#include "dawn/webgpu_cpp.h"
namespace dawn::native {
class DawnMockTest : public ::testing::Test {
public:
DawnMockTest();
~DawnMockTest() override;
protected:
::testing::NiceMock<DeviceMock>* mDeviceMock;
wgpu::Device device;
};
} // namespace dawn::native

View File

@ -0,0 +1,125 @@
// Copyright 2023 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 "dawn/tests/unittests/native/mocks/DeviceMock.h"
#include "dawn/tests/unittests/native/mocks/BindGroupLayoutMock.h"
#include "dawn/tests/unittests/native/mocks/BindGroupMock.h"
#include "dawn/tests/unittests/native/mocks/BufferMock.h"
#include "dawn/tests/unittests/native/mocks/ComputePipelineMock.h"
#include "dawn/tests/unittests/native/mocks/ExternalTextureMock.h"
#include "dawn/tests/unittests/native/mocks/PipelineLayoutMock.h"
#include "dawn/tests/unittests/native/mocks/QuerySetMock.h"
#include "dawn/tests/unittests/native/mocks/QueueMock.h"
#include "dawn/tests/unittests/native/mocks/RenderPipelineMock.h"
#include "dawn/tests/unittests/native/mocks/SamplerMock.h"
#include "dawn/tests/unittests/native/mocks/ShaderModuleMock.h"
#include "dawn/tests/unittests/native/mocks/TextureMock.h"
namespace dawn::native {
using ::testing::NiceMock;
using ::testing::WithArgs;
DeviceMock::DeviceMock() {
mInstance = InstanceBase::Create();
// Set all default creation functions to return nice mock objects.
ON_CALL(*this, CreateBindGroupImpl)
.WillByDefault(WithArgs<0>(
[this](const BindGroupDescriptor* descriptor) -> ResultOrError<Ref<BindGroupBase>> {
return AcquireRef(new NiceMock<BindGroupMock>(this, descriptor));
}));
ON_CALL(*this, CreateBindGroupLayoutImpl)
.WillByDefault(WithArgs<0, 1>([this](const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken)
-> ResultOrError<Ref<BindGroupLayoutBase>> {
return AcquireRef(
new NiceMock<BindGroupLayoutMock>(this, descriptor, pipelineCompatibilityToken));
}));
ON_CALL(*this, CreateBufferImpl)
.WillByDefault(WithArgs<0>(
[this](const BufferDescriptor* descriptor) -> ResultOrError<Ref<BufferBase>> {
return AcquireRef(new NiceMock<BufferMock>(this, descriptor));
}));
ON_CALL(*this, CreateExternalTextureImpl)
.WillByDefault(WithArgs<0>([this](const ExternalTextureDescriptor* descriptor)
-> ResultOrError<Ref<ExternalTextureBase>> {
return ExternalTextureMock::Create(this, descriptor);
}));
ON_CALL(*this, CreatePipelineLayoutImpl)
.WillByDefault(WithArgs<0>([this](const PipelineLayoutDescriptor* descriptor)
-> ResultOrError<Ref<PipelineLayoutBase>> {
return AcquireRef(new NiceMock<PipelineLayoutMock>(this, descriptor));
}));
ON_CALL(*this, CreateQuerySetImpl)
.WillByDefault(WithArgs<0>(
[this](const QuerySetDescriptor* descriptor) -> ResultOrError<Ref<QuerySetBase>> {
return AcquireRef(new NiceMock<QuerySetMock>(this, descriptor));
}));
ON_CALL(*this, CreateSamplerImpl)
.WillByDefault(WithArgs<0>(
[this](const SamplerDescriptor* descriptor) -> ResultOrError<Ref<SamplerBase>> {
return AcquireRef(new NiceMock<SamplerMock>(this, descriptor));
}));
ON_CALL(*this, CreateShaderModuleImpl)
.WillByDefault(WithArgs<0>([this](const ShaderModuleDescriptor* descriptor)
-> ResultOrError<Ref<ShaderModuleBase>> {
return ShaderModuleMock::Create(this, descriptor);
}));
ON_CALL(*this, CreateTextureImpl)
.WillByDefault(WithArgs<0>(
[this](const TextureDescriptor* descriptor) -> ResultOrError<Ref<TextureBase>> {
return AcquireRef(new NiceMock<TextureMock>(this, descriptor));
}));
ON_CALL(*this, CreateTextureViewImpl)
.WillByDefault(WithArgs<0, 1>(
[](TextureBase* texture,
const TextureViewDescriptor* descriptor) -> ResultOrError<Ref<TextureViewBase>> {
return AcquireRef(new NiceMock<TextureViewMock>(texture, descriptor));
}));
ON_CALL(*this, CreateUninitializedComputePipelineImpl)
.WillByDefault(WithArgs<0>(
[this](const ComputePipelineDescriptor* descriptor) -> Ref<ComputePipelineBase> {
return ComputePipelineMock::Create(this, descriptor);
}));
ON_CALL(*this, CreateUninitializedRenderPipelineImpl)
.WillByDefault(WithArgs<0>(
[this](const RenderPipelineDescriptor* descriptor) -> Ref<RenderPipelineBase> {
return RenderPipelineMock::Create(this, descriptor);
}));
// By default, the mock's TickImpl will succeed.
ON_CALL(*this, TickImpl).WillByDefault([]() -> MaybeError { return {}; });
// Initialize the device.
QueueDescriptor desc = {};
EXPECT_FALSE(Initialize(AcquireRef(new NiceMock<QueueMock>(this, &desc))).IsError());
}
DeviceMock::~DeviceMock() = default;
dawn::platform::Platform* DeviceMock::GetPlatform() const {
return mInstance->GetPlatform();
}
QueueMock* DeviceMock::GetQueueMock() {
return reinterpret_cast<QueueMock*>(GetQueue());
}
BindGroupLayoutMock* DeviceMock::GetEmptyBindGroupLayoutMock() {
return reinterpret_cast<BindGroupLayoutMock*>(GetEmptyBindGroupLayout());
}
} // namespace dawn::native

View File

@ -18,17 +18,34 @@
#include <memory> #include <memory>
#include "dawn/native/Device.h" #include "dawn/native/Device.h"
#include "dawn/native/Instance.h"
#include "dawn/native/RenderPipeline.h" #include "dawn/native/RenderPipeline.h"
#include "dawn/platform/DawnPlatform.h"
#include "dawn/tests/unittests/native/mocks/QueueMock.h"
#include "gmock/gmock.h" #include "gmock/gmock.h"
namespace dawn::native { namespace dawn::native {
class BindGroupLayoutMock;
class DeviceMock : public DeviceBase { class DeviceMock : public DeviceBase {
public: public:
// Exposes some protected functions for testing purposes. // Exposes some protected functions for testing purposes.
using DeviceBase::DestroyObjects; using DeviceBase::DestroyObjects;
using DeviceBase::ForceSetToggleForTesting; using DeviceBase::ForceSetToggleForTesting;
// TODO(lokokung): Use real DeviceBase constructor instead of mock specific one.
// - Requires AdapterMock.
// - Can probably remove GetPlatform overload.
// - Allows removing ForceSetToggleForTesting calls.
DeviceMock();
~DeviceMock() override;
dawn::platform::Platform* GetPlatform() const override;
// Mock specific functionality.
QueueMock* GetQueueMock();
BindGroupLayoutMock* GetEmptyBindGroupLayoutMock();
MOCK_METHOD(ResultOrError<Ref<CommandBufferBase>>, MOCK_METHOD(ResultOrError<Ref<CommandBufferBase>>,
CreateCommandBuffer, CreateCommandBuffer,
(CommandEncoder*, const CommandBufferDescriptor*), (CommandEncoder*, const CommandBufferDescriptor*),
@ -114,6 +131,9 @@ class DeviceMock : public DeviceBase {
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));
MOCK_METHOD(MaybeError, WaitForIdleForDestruction, (), (override)); MOCK_METHOD(MaybeError, WaitForIdleForDestruction, (), (override));
MOCK_METHOD(bool, HasPendingCommands, (), (const, override)); MOCK_METHOD(bool, HasPendingCommands, (), (const, override));
private:
Ref<InstanceBase> mInstance;
}; };
} // namespace dawn::native } // namespace dawn::native

View File

@ -16,7 +16,11 @@
namespace dawn::native { namespace dawn::native {
ExternalTextureMock::ExternalTextureMock(DeviceBase* device) : ExternalTextureBase(device) { using ::testing::NiceMock;
ExternalTextureMock::ExternalTextureMock(DeviceMock* device,
const ExternalTextureDescriptor* descriptor)
: ExternalTextureBase(device, descriptor) {
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { ON_CALL(*this, DestroyImpl).WillByDefault([this]() {
this->ExternalTextureBase::DestroyImpl(); this->ExternalTextureBase::DestroyImpl();
}); });
@ -24,4 +28,14 @@ ExternalTextureMock::ExternalTextureMock(DeviceBase* device) : ExternalTextureBa
ExternalTextureMock::~ExternalTextureMock() = default; ExternalTextureMock::~ExternalTextureMock() = default;
// static
Ref<ExternalTextureMock> ExternalTextureMock::Create(DeviceMock* device,
const ExternalTextureDescriptor* descriptor) {
Ref<ExternalTextureMock> externalTexture =
AcquireRef(new NiceMock<ExternalTextureMock>(device, descriptor));
externalTexture->Initialize(device, descriptor).AcquireSuccess();
return externalTexture;
}
} // namespace dawn::native } // namespace dawn::native

View File

@ -17,17 +17,23 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/Device.h"
#include "dawn/native/ExternalTexture.h" #include "dawn/native/ExternalTexture.h"
#include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class ExternalTextureMock : public ExternalTextureBase { class ExternalTextureMock : public ExternalTextureBase {
public: public:
explicit ExternalTextureMock(DeviceBase* device); // Creates an external texture mock based on a descriptor.
static Ref<ExternalTextureMock> Create(DeviceMock* device,
const ExternalTextureDescriptor* descriptor);
~ExternalTextureMock() override; ~ExternalTextureMock() override;
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));
protected:
ExternalTextureMock(DeviceMock* device, const ExternalTextureDescriptor* descriptor);
}; };
} // namespace dawn::native } // namespace dawn::native

View File

@ -16,10 +16,14 @@
namespace dawn::native { namespace dawn::native {
PipelineLayoutMock::PipelineLayoutMock(DeviceBase* device) : PipelineLayoutBase(device) { PipelineLayoutMock::PipelineLayoutMock(DeviceMock* device,
const PipelineLayoutDescriptor* descriptor)
: PipelineLayoutBase(device, descriptor) {
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { ON_CALL(*this, DestroyImpl).WillByDefault([this]() {
this->PipelineLayoutBase::DestroyImpl(); this->PipelineLayoutBase::DestroyImpl();
}); });
SetContentHash(ComputeContentHash());
} }
PipelineLayoutMock::~PipelineLayoutMock() = default; PipelineLayoutMock::~PipelineLayoutMock() = default;

View File

@ -17,14 +17,14 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/Device.h"
#include "dawn/native/PipelineLayout.h" #include "dawn/native/PipelineLayout.h"
#include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class PipelineLayoutMock : public PipelineLayoutBase { class PipelineLayoutMock : public PipelineLayoutBase {
public: public:
explicit PipelineLayoutMock(DeviceBase* device); PipelineLayoutMock(DeviceMock* device, const PipelineLayoutDescriptor* descriptor);
~PipelineLayoutMock() override; ~PipelineLayoutMock() override;
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));

View File

@ -16,7 +16,8 @@
namespace dawn::native { namespace dawn::native {
QuerySetMock::QuerySetMock(DeviceBase* device) : QuerySetBase(device) { QuerySetMock::QuerySetMock(DeviceMock* device, const QuerySetDescriptor* descriptor)
: QuerySetBase(device, descriptor) {
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->QuerySetBase::DestroyImpl(); }); ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->QuerySetBase::DestroyImpl(); });
} }

View File

@ -17,14 +17,14 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/Device.h"
#include "dawn/native/QuerySet.h" #include "dawn/native/QuerySet.h"
#include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class QuerySetMock : public QuerySetBase { class QuerySetMock : public QuerySetBase {
public: public:
explicit QuerySetMock(DeviceBase* device); QuerySetMock(DeviceMock* device, const QuerySetDescriptor* descriptor);
~QuerySetMock() override; ~QuerySetMock() override;
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));

View File

@ -0,0 +1,28 @@
// Copyright 2023 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 "dawn/tests/unittests/native/mocks/QueueMock.h"
#include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native {
QueueMock::QueueMock(DeviceMock* device, const QueueDescriptor* descriptor)
: QueueBase(device, descriptor) {
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->QueueBase::DestroyImpl(); });
}
QueueMock::~QueueMock() = default;
} // namespace dawn::native

View File

@ -0,0 +1,45 @@
// Copyright 2023 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 SRC_DAWN_TESTS_UNITTESTS_NATIVE_MOCKS_QUEUEMOCK_H_
#define SRC_DAWN_TESTS_UNITTESTS_NATIVE_MOCKS_QUEUEMOCK_H_
#include "gmock/gmock.h"
#include "dawn/native/Queue.h"
namespace dawn::native {
class DeviceMock;
class QueueMock : public QueueBase {
public:
QueueMock(DeviceMock* device, const QueueDescriptor* descriptor);
~QueueMock() override;
MOCK_METHOD(MaybeError, SubmitImpl, (uint32_t, CommandBufferBase* const*), (override));
MOCK_METHOD(MaybeError,
WriteBufferImpl,
(BufferBase*, uint64_t, const void*, size_t),
(override));
MOCK_METHOD(MaybeError,
WriteTextureImpl,
(const ImageCopyTexture&, const void*, const TextureDataLayout&, const Extent3D&),
(override));
MOCK_METHOD(void, DestroyImpl, (), (override));
};
} // namespace dawn::native
#endif // SRC_DAWN_TESTS_UNITTESTS_NATIVE_MOCKS_QUEUEMOCK_H_

View File

@ -16,7 +16,12 @@
namespace dawn::native { namespace dawn::native {
RenderPipelineMock::RenderPipelineMock(DeviceBase* device) : RenderPipelineBase(device) { using ::testing::NiceMock;
RenderPipelineMock::RenderPipelineMock(DeviceMock* device,
const RenderPipelineDescriptor* descriptor)
: RenderPipelineBase(device, descriptor) {
ON_CALL(*this, Initialize).WillByDefault([]() -> MaybeError { return {}; });
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { ON_CALL(*this, DestroyImpl).WillByDefault([this]() {
this->RenderPipelineBase::DestroyImpl(); this->RenderPipelineBase::DestroyImpl();
}); });
@ -24,4 +29,14 @@ RenderPipelineMock::RenderPipelineMock(DeviceBase* device) : RenderPipelineBase(
RenderPipelineMock::~RenderPipelineMock() = default; RenderPipelineMock::~RenderPipelineMock() = default;
// static
Ref<RenderPipelineMock> RenderPipelineMock::Create(DeviceMock* device,
const RenderPipelineDescriptor* descriptor) {
RenderPipelineDescriptor appliedDescriptor;
Ref<PipelineLayoutBase> layoutRef = ValidateLayoutAndGetRenderPipelineDescriptorWithDefaults(
device, *descriptor, &appliedDescriptor)
.AcquireSuccess();
return AcquireRef(new NiceMock<RenderPipelineMock>(device, &appliedDescriptor));
}
} // namespace dawn::native } // namespace dawn::native

View File

@ -17,19 +17,24 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/Device.h"
#include "dawn/native/RenderPipeline.h" #include "dawn/native/RenderPipeline.h"
#include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class RenderPipelineMock : public RenderPipelineBase { class RenderPipelineMock : public RenderPipelineBase {
public: public:
explicit RenderPipelineMock(DeviceBase* device); // Creates a compute pipeline given the descriptor.
static Ref<RenderPipelineMock> Create(DeviceMock* device,
const RenderPipelineDescriptor* descriptor);
~RenderPipelineMock() override; ~RenderPipelineMock() override;
MOCK_METHOD(MaybeError, Initialize, (), (override)); MOCK_METHOD(MaybeError, Initialize, (), (override));
MOCK_METHOD(size_t, ComputeContentHash, (), (override));
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));
protected:
RenderPipelineMock(DeviceMock* device, const RenderPipelineDescriptor* descriptor);
}; };
} // namespace dawn::native } // namespace dawn::native

View File

@ -16,8 +16,11 @@
namespace dawn::native { namespace dawn::native {
SamplerMock::SamplerMock(DeviceBase* device) : SamplerBase(device) { SamplerMock::SamplerMock(DeviceMock* device, const SamplerDescriptor* descriptor)
: SamplerBase(device, descriptor) {
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->SamplerBase::DestroyImpl(); }); ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->SamplerBase::DestroyImpl(); });
SetContentHash(ComputeContentHash());
} }
SamplerMock::~SamplerMock() = default; SamplerMock::~SamplerMock() = default;

View File

@ -17,14 +17,14 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/Device.h"
#include "dawn/native/Sampler.h" #include "dawn/native/Sampler.h"
#include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class SamplerMock : public SamplerBase { class SamplerMock : public SamplerBase {
public: public:
explicit SamplerMock(DeviceBase* device); SamplerMock(DeviceMock* device, const SamplerDescriptor* descriptor);
~SamplerMock() override; ~SamplerMock() override;
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));

View File

@ -14,27 +14,39 @@
#include "dawn/tests/unittests/native/mocks/ShaderModuleMock.h" #include "dawn/tests/unittests/native/mocks/ShaderModuleMock.h"
#include "dawn/native/ChainUtils_autogen.h"
namespace dawn::native { namespace dawn::native {
ShaderModuleMock::ShaderModuleMock(DeviceBase* device) : ShaderModuleBase(device) { using ::testing::NiceMock;
ShaderModuleMock::ShaderModuleMock(DeviceMock* device, const ShaderModuleDescriptor* descriptor)
: ShaderModuleBase(device, descriptor) {
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->ShaderModuleBase::DestroyImpl(); }); ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->ShaderModuleBase::DestroyImpl(); });
SetContentHash(ComputeContentHash());
} }
ShaderModuleMock::~ShaderModuleMock() = default; ShaderModuleMock::~ShaderModuleMock() = default;
ResultOrError<Ref<ShaderModuleMock>> ShaderModuleMock::Create(DeviceBase* device, // static
const char* source) { Ref<ShaderModuleMock> ShaderModuleMock::Create(DeviceMock* device,
ShaderModuleMock* mock = new ShaderModuleMock(device); const ShaderModuleDescriptor* descriptor) {
Ref<ShaderModuleMock> shaderModule =
ShaderModuleWGSLDescriptor wgslDesc; AcquireRef(new NiceMock<ShaderModuleMock>(device, descriptor));
wgslDesc.source = source;
ShaderModuleDescriptor desc;
desc.nextInChain = &wgslDesc;
ShaderModuleParseResult parseResult; ShaderModuleParseResult parseResult;
DAWN_TRY(ValidateAndParseShaderModule(device, &desc, &parseResult, nullptr)); ValidateAndParseShaderModule(device, descriptor, &parseResult, nullptr).AcquireSuccess();
DAWN_TRY(mock->InitializeBase(&parseResult, nullptr)); shaderModule->InitializeBase(&parseResult, nullptr).AcquireSuccess();
return AcquireRef(mock); return shaderModule;
}
// static
Ref<ShaderModuleMock> ShaderModuleMock::Create(DeviceMock* device, const char* source) {
ShaderModuleWGSLDescriptor wgslDesc = {};
wgslDesc.source = source;
ShaderModuleDescriptor desc = {};
desc.nextInChain = &wgslDesc;
return Create(device, &desc);
} }
} // namespace dawn::native } // namespace dawn::native

View File

@ -15,25 +15,26 @@
#ifndef SRC_DAWN_TESTS_UNITTESTS_NATIVE_MOCKS_SHADERMODULEMOCK_H_ #ifndef SRC_DAWN_TESTS_UNITTESTS_NATIVE_MOCKS_SHADERMODULEMOCK_H_
#define SRC_DAWN_TESTS_UNITTESTS_NATIVE_MOCKS_SHADERMODULEMOCK_H_ #define SRC_DAWN_TESTS_UNITTESTS_NATIVE_MOCKS_SHADERMODULEMOCK_H_
#include <memory>
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/Device.h"
#include "dawn/native/Error.h"
#include "dawn/native/ShaderModule.h" #include "dawn/native/ShaderModule.h"
#include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class ShaderModuleMock : public ShaderModuleBase { class ShaderModuleMock : public ShaderModuleBase {
public: public:
explicit ShaderModuleMock(DeviceBase* device); // Creates a shader module mock based on a descriptor or wgsl source.
static Ref<ShaderModuleMock> Create(DeviceMock* device,
const ShaderModuleDescriptor* descriptor);
static Ref<ShaderModuleMock> Create(DeviceMock* device, const char* source);
~ShaderModuleMock() override; ~ShaderModuleMock() override;
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));
// Creates a shader module mock based on the wgsl source. protected:
static ResultOrError<Ref<ShaderModuleMock>> Create(DeviceBase* device, const char* source); ShaderModuleMock(DeviceMock* device, const ShaderModuleDescriptor* descriptor);
}; };
} // namespace dawn::native } // namespace dawn::native

View File

@ -16,14 +16,19 @@
namespace dawn::native { namespace dawn::native {
TextureMock::TextureMock(DeviceBase* device, TextureBase::TextureState state) TextureMock::TextureMock(DeviceMock* device,
: TextureBase(device, state) { const TextureDescriptor* descriptor,
TextureBase::TextureState state)
: TextureBase(device, descriptor, state) {
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->TextureBase::DestroyImpl(); }); ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->TextureBase::DestroyImpl(); });
} }
TextureMock::~TextureMock() = default; TextureMock::~TextureMock() = default;
TextureViewMock::TextureViewMock(TextureBase* texture) : TextureViewBase(texture) {} TextureViewMock::TextureViewMock(TextureBase* texture, const TextureViewDescriptor* descriptor)
: TextureViewBase(texture, descriptor) {
ON_CALL(*this, DestroyImpl).WillByDefault([this]() { this->TextureViewBase::DestroyImpl(); });
}
TextureViewMock::~TextureViewMock() = default; TextureViewMock::~TextureViewMock() = default;

View File

@ -17,14 +17,16 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "dawn/native/Device.h"
#include "dawn/native/Texture.h" #include "dawn/native/Texture.h"
#include "dawn/tests/unittests/native/mocks/DeviceMock.h"
namespace dawn::native { namespace dawn::native {
class TextureMock : public TextureBase { class TextureMock : public TextureBase {
public: public:
TextureMock(DeviceBase* device, TextureBase::TextureState state); TextureMock(DeviceMock* device,
const TextureDescriptor* descriptor,
TextureBase::TextureState state = TextureBase::TextureState::OwnedInternal);
~TextureMock() override; ~TextureMock() override;
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));
@ -32,7 +34,7 @@ class TextureMock : public TextureBase {
class TextureViewMock : public TextureViewBase { class TextureViewMock : public TextureViewBase {
public: public:
explicit TextureViewMock(TextureBase* texture); TextureViewMock(TextureBase* texture, const TextureViewDescriptor* descriptor);
~TextureViewMock() override; ~TextureViewMock() override;
MOCK_METHOD(void, DestroyImpl, (), (override)); MOCK_METHOD(void, DestroyImpl, (), (override));