Emulate store and multisample resolve on Metal

This patch implements "store and MSAA resolve" store operation on Metal
drivers that don't support MTLStoreActionStoreAndMultisampleResolve with
a workaround that does MSAA resolve in another render pass.

Driver workaround is one type of Dawn Toggles. Dawn Toggles will include
other optional optimizations and features that can be configured to use
or not when we create Dawn Devices.

As all Metal try bots don't need this toggle, to better test this
patch on the try bots:
1. We add the support of forcing enabling a workaround when starting an
   Dawn end2end test so that we can test the workaround on the platforms
   where the workaround is disabled.
2. We add an optional parameter DeviceDescriptor to CreateDevice() so
   that we can custom the toggles the Dawn device should use.

This patch also adds the support of querying toggle details from Instance
and the names of the toggles in use from Device. These APIs are tested in
the Dawn unittests added in this patch.

BUG=dawn:56
TEST=dawn_end2end_tests
TEST=dawn_unittests

Change-Id: Iae31d2ded6057eee638b6099d3061e9d78b04d55
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/6620
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
Jiawei Shao
2019-04-26 07:52:57 +00:00
committed by Commit Bot service account
parent 8e97b4c8a5
commit 15d4c2e63b
34 changed files with 505 additions and 97 deletions

View File

@@ -0,0 +1,72 @@
// Copyright 2019 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"
namespace {
class ToggleValidationTest : public ValidationTest {
};
// Tests querying the detail of a toggle from dawn_native::InstanceBase works correctly.
TEST_F(ToggleValidationTest, QueryToggleInfo) {
// Query with a valid toggle name
{
const char* kValidToggleName = "emulate_store_and_msaa_resolve";
const dawn_native::ToggleInfo* toggleInfo = instance->GetToggleInfo(kValidToggleName);
ASSERT_NE(nullptr, toggleInfo);
ASSERT_NE(nullptr, toggleInfo->name);
ASSERT_NE(nullptr, toggleInfo->description);
ASSERT_NE(nullptr, toggleInfo->url);
}
// Query with an invalid toggle name
{
const char* kInvalidToggleName = "!@#$%^&*";
const dawn_native::ToggleInfo* toggleInfo = instance->GetToggleInfo(kInvalidToggleName);
ASSERT_EQ(nullptr, toggleInfo);
}
}
// Tests overriding toggles when creating a device works correctly.
TEST_F(ToggleValidationTest, OverrideToggleUsage) {
// Dawn unittests use null Adapters, so there should be no toggles that are enabled by default
{
std::vector<const char*> toggleNames = dawn_native::GetTogglesUsed(device.Get());
ASSERT_EQ(0u, toggleNames.size());
}
// Create device with a valid name of a toggle
{
const char* kValidToggleName = "emulate_store_and_msaa_resolve";
dawn_native::DeviceDescriptor descriptor;
descriptor.forceEnabledToggles.push_back(kValidToggleName);
DawnDevice deviceWithToggle = adapter.CreateDevice(&descriptor);
std::vector<const char*> toggleNames = dawn_native::GetTogglesUsed(deviceWithToggle);
ASSERT_EQ(1u, toggleNames.size());
ASSERT_EQ(0, strcmp(kValidToggleName, toggleNames[0]));
}
// Create device with an invalid toggle name
{
dawn_native::DeviceDescriptor descriptor;
descriptor.forceEnabledToggles.push_back("!@#$%^&*");
DawnDevice deviceWithToggle = adapter.CreateDevice(&descriptor);
std::vector<const char*> toggleNames = dawn_native::GetTogglesUsed(deviceWithToggle);
ASSERT_EQ(0u, toggleNames.size());
}
}
} // anonymous namespace

View File

@@ -16,28 +16,26 @@
#include "common/Assert.h"
#include "dawn/dawn.h"
#include "dawn_native/DawnNative.h"
#include "dawn_native/NullBackend.h"
ValidationTest::ValidationTest() {
mInstance = std::make_unique<dawn_native::Instance>();
mInstance->DiscoverDefaultAdapters();
instance = std::make_unique<dawn_native::Instance>();
instance->DiscoverDefaultAdapters();
std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters();
std::vector<dawn_native::Adapter> adapters = instance->GetAdapters();
// Validation tests run against the null backend, find the corresponding adapter
bool foundNullAdapter = false;
dawn_native::Adapter nullAdapter;
for (auto adapter : adapters) {
if (adapter.GetBackendType() == dawn_native::BackendType::Null) {
nullAdapter = adapter;
for (auto &currentAdapter : adapters) {
if (currentAdapter.GetBackendType() == dawn_native::BackendType::Null) {
adapter = currentAdapter;
foundNullAdapter = true;
break;
}
}
ASSERT(foundNullAdapter);
device = dawn::Device::Acquire(nullAdapter.CreateDevice());
device = dawn::Device::Acquire(adapter.CreateDevice());
DawnProcTable procs = dawn_native::GetProcs();
dawnSetProcs(&procs);

View File

@@ -17,10 +17,7 @@
#include "gtest/gtest.h"
#include "dawn/dawncpp.h"
namespace dawn_native {
class Instance;
}
#include "dawn_native/DawnNative.h"
#define ASSERT_DEVICE_ERROR(statement) \
StartExpectDeviceError(); \
@@ -55,10 +52,10 @@ class ValidationTest : public testing::Test {
protected:
dawn::Device device;
dawn_native::Adapter adapter;
std::unique_ptr<dawn_native::Instance> instance;
private:
std::unique_ptr<dawn_native::Instance> mInstance;
static void OnDeviceError(const char* message, DawnCallbackUserdata userdata);
std::string mDeviceErrorMessage;
bool mExpectError = false;