// Copyright 2017 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 "tests/unittests/validation/ValidationTest.h" #include "dawn/dawn.h" namespace dawn_native { namespace null { void Init(dawnProcTable* procs, dawnDevice* device); } } ValidationTest::ValidationTest() { dawnProcTable procs; dawnDevice cDevice; dawn_native::null::Init(&procs, &cDevice); dawnSetProcs(&procs); device = dawn::Device::Acquire(cDevice); device.SetErrorCallback(ValidationTest::OnDeviceError, static_cast(reinterpret_cast(this))); } ValidationTest::~ValidationTest() { // We need to destroy Dawn objects before setting the procs to null otherwise the dawn*Release // will call a nullptr device = dawn::Device(); dawnSetProcs(nullptr); } void ValidationTest::TearDown() { ASSERT_FALSE(mExpectError); for (auto& expectation : mExpectations) { std::string name = expectation.debugName; if (name.empty()) { name = ""; } ASSERT_TRUE(expectation.gotStatus) << "Didn't get a status for " << name; ASSERT_NE(DAWN_BUILDER_ERROR_STATUS_UNKNOWN, expectation.status) << "Got unknown status for " << name; bool wasSuccess = expectation.status == DAWN_BUILDER_ERROR_STATUS_SUCCESS; ASSERT_EQ(expectation.expectSuccess, wasSuccess) << "Got wrong status value for " << name << ", status was " << expectation.status << " with \"" << expectation.statusMessage << "\""; } } void ValidationTest::StartExpectDeviceError() { mExpectError = true; mError = false; } bool ValidationTest::EndExpectDeviceError() { mExpectError = false; return mError; } dawn::RenderPassDescriptor ValidationTest::CreateSimpleRenderPass() { auto colorBuffer = device.CreateTextureBuilder() .SetDimension(dawn::TextureDimension::e2D) .SetExtent(640, 480, 1) .SetFormat(dawn::TextureFormat::R8G8B8A8Unorm) .SetMipLevels(1) .SetAllowedUsage(dawn::TextureUsageBit::OutputAttachment) .GetResult(); auto colorView = colorBuffer.CreateTextureViewBuilder() .GetResult(); return device.CreateRenderPassDescriptorBuilder() .SetColorAttachment(0, colorView, dawn::LoadOp::Clear) .GetResult(); } void ValidationTest::OnDeviceError(const char* message, dawnCallbackUserdata userdata) { // Skip this one specific error that is raised when a builder is used after it got an error // this is important because we don't want to wrap all creation tests in ASSERT_DEVICE_ERROR. // Yes the error message is misleading. if (std::string(message) == "Builder cannot be used after GetResult") { return; } auto self = reinterpret_cast(static_cast(userdata)); ASSERT_TRUE(self->mExpectError) << "Got unexpected device error: " << message; ASSERT_FALSE(self->mError) << "Got two errors in expect block"; self->mError = true; } void ValidationTest::OnBuilderErrorStatus(dawnBuilderErrorStatus status, const char* message, dawn::CallbackUserdata userdata1, dawn::CallbackUserdata userdata2) { auto* self = reinterpret_cast(static_cast(userdata1)); size_t index = static_cast(userdata2); ASSERT_LT(index, self->mExpectations.size()); auto& expectation = self->mExpectations[index]; ASSERT_FALSE(expectation.gotStatus); expectation.gotStatus = true; expectation.status = status; expectation.statusMessage = message; } ValidationTest::DummyRenderPass ValidationTest::CreateDummyRenderPass() { DummyRenderPass dummy; dummy.width = 400; dummy.height = 400; dummy.attachmentFormat = dawn::TextureFormat::R8G8B8A8Unorm; dummy.attachment = AssertWillBeSuccess(device.CreateTextureBuilder()) .SetDimension(dawn::TextureDimension::e2D) .SetExtent(dummy.width, dummy.height, 1) .SetFormat(dummy.attachmentFormat) .SetMipLevels(1) .SetAllowedUsage(dawn::TextureUsageBit::OutputAttachment) .GetResult(); dawn::TextureView view = AssertWillBeSuccess(dummy.attachment.CreateTextureViewBuilder()).GetResult(); dummy.renderPass = AssertWillBeSuccess(device.CreateRenderPassDescriptorBuilder()) .SetColorAttachment(0, view, dawn::LoadOp::Clear) .GetResult(); return dummy; }