282 lines
12 KiB
C++
282 lines
12 KiB
C++
// 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 <memory>
|
|
#include <vector>
|
|
|
|
#include "dawn/dawn_proc.h"
|
|
#include "dawn/native/Adapter.h"
|
|
#include "dawn/native/DawnNative.h"
|
|
#include "dawn/native/Device.h"
|
|
#include "dawn/native/Instance.h"
|
|
#include "dawn/native/Toggles.h"
|
|
#include "dawn/native/dawn_platform.h"
|
|
#include "dawn/tests/MockCallback.h"
|
|
#include "dawn/utils/SystemUtils.h"
|
|
#include "dawn/utils/WGPUHelpers.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
namespace dawn {
|
|
namespace {
|
|
|
|
using testing::Contains;
|
|
using testing::MockCallback;
|
|
using testing::NotNull;
|
|
using testing::SaveArg;
|
|
using testing::StrEq;
|
|
|
|
class InstanceToggleTest : public testing::Test {
|
|
protected:
|
|
void SetUp() override { dawnProcSetProcs(&native::GetProcs()); }
|
|
|
|
void TearDown() override { dawnProcSetProcs(nullptr); }
|
|
};
|
|
|
|
// Test that instance toggles are set by requirement or default as expected.
|
|
TEST_F(InstanceToggleTest, InstanceTogglesSet) {
|
|
auto validateInstanceToggles = [](const native::Instance* nativeInstance,
|
|
std::initializer_list<const char*> enableToggles,
|
|
std::initializer_list<const char*> disableToggles) {
|
|
const native::InstanceBase* instance = native::FromAPI(nativeInstance->Get());
|
|
const native::TogglesState& instanceTogglesState = instance->GetTogglesState();
|
|
std::vector<const char*> enabledToggles = instanceTogglesState.GetEnabledToggleNames();
|
|
std::vector<const char*> disabledToggles = instanceTogglesState.GetDisabledToggleNames();
|
|
EXPECT_EQ(disabledToggles.size(), disableToggles.size());
|
|
EXPECT_EQ(enabledToggles.size(), enableToggles.size());
|
|
for (auto* enableToggle : enableToggles) {
|
|
EXPECT_THAT(enabledToggles, Contains(StrEq(enableToggle)));
|
|
}
|
|
for (auto* disableToggle : disableToggles) {
|
|
EXPECT_THAT(disabledToggles, Contains(StrEq(disableToggle)));
|
|
}
|
|
};
|
|
|
|
// Create instance with no toggles descriptor
|
|
{
|
|
std::unique_ptr<native::Instance> instance;
|
|
|
|
// Create an instance with default toggles, where AllowUnsafeAPIs is disabled and
|
|
// DisallowUnsafeAPIs is enabled.
|
|
instance = std::make_unique<native::Instance>();
|
|
validateInstanceToggles(instance.get(), {"disallow_unsafe_apis"}, {"allow_unsafe_apis"});
|
|
}
|
|
|
|
// Create instance with empty toggles descriptor
|
|
{
|
|
std::unique_ptr<native::Instance> instance;
|
|
|
|
// Make an instance descriptor chaining an empty toggles descriptor
|
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
|
|
|
WGPUInstanceDescriptor instanceDesc = {};
|
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
|
|
|
// Create an instance with default toggles, where AllowUnsafeAPIs is disabled and
|
|
// DisallowUnsafeAPIs is enabled.
|
|
instance = std::make_unique<native::Instance>(&instanceDesc);
|
|
validateInstanceToggles(instance.get(), {"disallow_unsafe_apis"}, {"allow_unsafe_apis"});
|
|
}
|
|
|
|
// Create instance with DisallowUnsafeAPIs explicitly enabled in toggles descriptor
|
|
{
|
|
std::unique_ptr<native::Instance> instance;
|
|
|
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
|
instanceTogglesDesc.enabledTogglesCount = 1;
|
|
instanceTogglesDesc.enabledToggles = &disallowUnsafeApisToggle;
|
|
|
|
WGPUInstanceDescriptor instanceDesc = {};
|
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
|
|
|
// Create an instance with DisallowUnsafeApis explicitly enabled.
|
|
instance = std::make_unique<native::Instance>(&instanceDesc);
|
|
validateInstanceToggles(instance.get(), {disallowUnsafeApisToggle}, {"allow_unsafe_apis"});
|
|
}
|
|
|
|
// Create instance with DisallowUnsafeAPIs explicitly disabled in toggles descriptor
|
|
{
|
|
std::unique_ptr<native::Instance> instance;
|
|
|
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
|
instanceTogglesDesc.disabledTogglesCount = 1;
|
|
instanceTogglesDesc.disabledToggles = &disallowUnsafeApisToggle;
|
|
|
|
WGPUInstanceDescriptor instanceDesc = {};
|
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
|
|
|
// Create an instance with DisallowUnsafeApis explicitly disabled.
|
|
instance = std::make_unique<native::Instance>(&instanceDesc);
|
|
validateInstanceToggles(instance.get(), {},
|
|
{disallowUnsafeApisToggle, "allow_unsafe_apis"});
|
|
}
|
|
|
|
// Create instance with AllowUnsafeAPIs explicitly enabled in toggles descriptor
|
|
{
|
|
std::unique_ptr<native::Instance> instance;
|
|
|
|
const char* allowUnsafeApisToggle = "allow_unsafe_apis";
|
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
|
instanceTogglesDesc.enabledTogglesCount = 1;
|
|
instanceTogglesDesc.enabledToggles = &allowUnsafeApisToggle;
|
|
|
|
WGPUInstanceDescriptor instanceDesc = {};
|
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
|
|
|
// Create an instance with AllowUnsafeAPIs explicitly enabled.
|
|
instance = std::make_unique<native::Instance>(&instanceDesc);
|
|
validateInstanceToggles(instance.get(), {allowUnsafeApisToggle, "disallow_unsafe_apis"},
|
|
{});
|
|
}
|
|
|
|
// Create instance with AllowUnsafeAPIs explicitly disabled in toggles descriptor
|
|
{
|
|
std::unique_ptr<native::Instance> instance;
|
|
|
|
const char* allowUnsafeApisToggle = "allow_unsafe_apis";
|
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
|
instanceTogglesDesc.disabledTogglesCount = 1;
|
|
instanceTogglesDesc.disabledToggles = &allowUnsafeApisToggle;
|
|
|
|
WGPUInstanceDescriptor instanceDesc = {};
|
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
|
|
|
// Create an instance with AllowUnsafeAPIs explicitly disabled.
|
|
instance = std::make_unique<native::Instance>(&instanceDesc);
|
|
validateInstanceToggles(instance.get(), {"disallow_unsafe_apis"}, {allowUnsafeApisToggle});
|
|
}
|
|
}
|
|
|
|
// Test that instance toggles are inherited to the adapters and devices it creates.
|
|
TEST_F(InstanceToggleTest, InstanceTogglesInheritToAdapterAndDevice) {
|
|
auto validateInstanceTogglesInheritedToAdapter = [&](native::Instance* nativeInstance) {
|
|
native::InstanceBase* instance = native::FromAPI(nativeInstance->Get());
|
|
const native::TogglesState& instanceTogglesState = instance->GetTogglesState();
|
|
|
|
// Discover physical devices.
|
|
instance->DiscoverDefaultPhysicalDevices();
|
|
|
|
// Get the adapters created by instance with default toggles.
|
|
Ref<native::AdapterBase> nullAdapter;
|
|
for (auto& adapter : instance->GetAdapters()) {
|
|
if (adapter->GetPhysicalDevice()->GetBackendType() == wgpu::BackendType::Null) {
|
|
nullAdapter = adapter;
|
|
break;
|
|
}
|
|
}
|
|
ASSERT_NE(nullAdapter, nullptr);
|
|
auto& adapterTogglesState = nullAdapter->GetTogglesState();
|
|
|
|
// Creater a default device.
|
|
native::DeviceBase* nullDevice = nullAdapter->APICreateDevice();
|
|
|
|
// Check instance toggles are inherited by adapter and device.
|
|
native::TogglesInfo togglesInfo;
|
|
static_assert(std::is_same_v<std::underlying_type_t<native::Toggle>, int>);
|
|
for (int i = 0; i < static_cast<int>(native::Toggle::EnumCount); i++) {
|
|
native::Toggle toggle = static_cast<native::Toggle>(i);
|
|
if (togglesInfo.GetToggleInfo(toggle)->stage != native::ToggleStage::Instance) {
|
|
continue;
|
|
}
|
|
EXPECT_EQ(instanceTogglesState.IsSet(toggle), adapterTogglesState.IsSet(toggle));
|
|
EXPECT_EQ(instanceTogglesState.IsEnabled(toggle),
|
|
adapterTogglesState.IsEnabled(toggle));
|
|
EXPECT_EQ(instanceTogglesState.IsEnabled(toggle), nullDevice->IsToggleEnabled(toggle));
|
|
}
|
|
|
|
nullDevice->Release();
|
|
};
|
|
|
|
// Create instance with DisallowUnsafeAPIs explicitly enabled in toggles descriptor
|
|
{
|
|
std::unique_ptr<native::Instance> instance;
|
|
|
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
|
instanceTogglesDesc.enabledTogglesCount = 1;
|
|
instanceTogglesDesc.enabledToggles = &disallowUnsafeApisToggle;
|
|
|
|
WGPUInstanceDescriptor instanceDesc = {};
|
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
|
|
|
// Create an instance with DisallowUnsafeApis explicitly enabled.
|
|
instance = std::make_unique<native::Instance>(&instanceDesc);
|
|
validateInstanceTogglesInheritedToAdapter(instance.get());
|
|
}
|
|
|
|
// Create instance with DisallowUnsafeAPIs explicitly disabled in toggles descriptor
|
|
{
|
|
std::unique_ptr<native::Instance> instance;
|
|
|
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
|
instanceTogglesDesc.disabledTogglesCount = 1;
|
|
instanceTogglesDesc.disabledToggles = &disallowUnsafeApisToggle;
|
|
|
|
WGPUInstanceDescriptor instanceDesc = {};
|
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
|
|
|
// Create an instance with DisallowUnsafeApis explicitly enabled.
|
|
instance = std::make_unique<native::Instance>(&instanceDesc);
|
|
validateInstanceTogglesInheritedToAdapter(instance.get());
|
|
}
|
|
|
|
// Create instance with AllowUnsafeAPIs explicitly enabled in toggles descriptor
|
|
{
|
|
std::unique_ptr<native::Instance> instance;
|
|
|
|
const char* allowUnsafeApisToggle = "allow_unsafe_apis";
|
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
|
instanceTogglesDesc.enabledTogglesCount = 1;
|
|
instanceTogglesDesc.enabledToggles = &allowUnsafeApisToggle;
|
|
|
|
WGPUInstanceDescriptor instanceDesc = {};
|
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
|
|
|
// Create an instance with DisallowUnsafeApis explicitly enabled.
|
|
instance = std::make_unique<native::Instance>(&instanceDesc);
|
|
validateInstanceTogglesInheritedToAdapter(instance.get());
|
|
}
|
|
|
|
// Create instance with AllowUnsafeAPIs explicitly disabled in toggles descriptor
|
|
{
|
|
std::unique_ptr<native::Instance> instance;
|
|
|
|
const char* allowUnsafeApisToggle = "allow_unsafe_apis";
|
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
|
instanceTogglesDesc.disabledTogglesCount = 1;
|
|
instanceTogglesDesc.disabledToggles = &allowUnsafeApisToggle;
|
|
|
|
WGPUInstanceDescriptor instanceDesc = {};
|
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
|
|
|
// Create an instance with DisallowUnsafeApis explicitly enabled.
|
|
instance = std::make_unique<native::Instance>(&instanceDesc);
|
|
validateInstanceTogglesInheritedToAdapter(instance.get());
|
|
}
|
|
}
|
|
|
|
} // anonymous namespace
|
|
} // namespace dawn
|